summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
authorCarl Hetherington <cth@carlh.net>2023-05-20 22:51:49 +0200
committerCarl Hetherington <cth@carlh.net>2024-05-06 20:42:50 +0200
commita3fcbb3a76e079a5485a0552ea5d35b8d6739116 (patch)
tree58f6476b7197c0e32b5aa3d52d0859a9b04db268 /test
parenta4105c6e8dc83407abc9b12e80c958673c942888 (diff)
Use sqlite for cinema and DKDM recipient lists.
Diffstat (limited to 'test')
-rw-r--r--test/cinema_list_test.cc225
-rw-r--r--test/config_test.cc275
m---------test/data0
-rw-r--r--test/dkdm_recipient_list_test.cc56
-rw-r--r--test/kdm_cli_test.cc25
-rw-r--r--test/kdm_naming_test.cc74
-rw-r--r--test/recover_test.cc3
-rw-r--r--test/test.cc3
-rw-r--r--test/wscript4
9 files changed, 607 insertions, 58 deletions
diff --git a/test/cinema_list_test.cc b/test/cinema_list_test.cc
new file mode 100644
index 000000000..4aa9fa4ed
--- /dev/null
+++ b/test/cinema_list_test.cc
@@ -0,0 +1,225 @@
+/*
+ Copyright (C) 2023 Carl Hetherington <cth@carlh.net>
+
+ This file is part of DCP-o-matic.
+
+ DCP-o-matic is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ DCP-o-matic is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with DCP-o-matic. If not, see <http://www.gnu.org/licenses/>.
+
+*/
+
+
+#include "lib/cinema.h"
+#include "lib/cinema_list.h"
+#include "lib/config.h"
+#include "lib/screen.h"
+#include <dcp/certificate.h>
+#include <dcp/filesystem.h>
+#include <dcp/util.h>
+#include <boost/filesystem.hpp>
+#include <boost/test/unit_test.hpp>
+#include <list>
+#include <string>
+
+
+using std::pair;
+using std::string;
+using std::vector;
+
+
+static
+boost::filesystem::path
+setup(string name)
+{
+ boost::filesystem::path db = boost::filesystem::path("build") / "test" / (name + ".db");
+ boost::system::error_code ec;
+ boost::filesystem::remove(db, ec);
+ return db;
+}
+
+
+BOOST_AUTO_TEST_CASE(add_cinema_test)
+{
+ auto const db = setup("add_cinema_test");
+
+ auto const name = "Bob's Zero-G Cinema";
+ auto const emails = vector<string>{"zerogbob@hotmail.com"};
+ auto const notes = "Nice enough place but the popcorn keeps floating away";
+ auto const utc_offset = dcp::UTCOffset{5, 0};
+
+ CinemaList cinemas(db);
+ cinemas.add_cinema({name, emails, notes, utc_offset});
+
+ CinemaList cinemas2(db);
+ auto const check = cinemas2.cinemas();
+ BOOST_REQUIRE_EQUAL(check.size(), 1U);
+ BOOST_CHECK(check[0].second.name == name);
+ BOOST_CHECK(check[0].second.emails == emails);
+ BOOST_CHECK_EQUAL(check[0].second.notes, notes);
+ BOOST_CHECK(check[0].second.utc_offset == utc_offset);
+}
+
+
+BOOST_AUTO_TEST_CASE(remove_cinema_test)
+{
+ auto const db = setup("remove_cinema_test");
+
+ auto const name1 = "Bob's Zero-G Cinema";
+ auto const emails1 = vector<string>{"zerogbob@hotmail.com"};
+ auto const notes1 = "Nice enough place but the popcorn keeps floating away";
+ auto const utc_offset1 = dcp::UTCOffset{-4, -30};
+
+ auto const name2 = "Angie's Infinite-Screen Cinema";
+ auto const emails2 = vector<string>{"angie@infinitium.com", "projection-screen912341235@infinitium.com"};
+ auto const notes2 = "Nice enough place but it's very hard to find the right screen";
+ auto const utc_offset2 = dcp::UTCOffset{9, 0};
+
+ CinemaList cinemas(db);
+ auto const id1 = cinemas.add_cinema({name1, emails1, notes1, utc_offset1});
+ cinemas.add_cinema({name2, emails2, notes2, utc_offset2});
+
+ auto const check = cinemas.cinemas();
+ BOOST_REQUIRE_EQUAL(check.size(), 2U);
+ BOOST_CHECK(check[0].second.name == name2);
+ BOOST_CHECK(check[0].second.emails == emails2);
+ BOOST_CHECK_EQUAL(check[0].second.notes, notes2);
+ BOOST_CHECK(check[0].second.utc_offset == utc_offset2);
+ BOOST_CHECK(check[1].second.name == name1);
+ BOOST_CHECK(check[1].second.emails == emails1);
+ BOOST_CHECK_EQUAL(check[1].second.notes, notes1);
+ BOOST_CHECK(check[1].second.utc_offset == utc_offset1);
+
+ cinemas.remove_cinema(id1);
+
+ auto const check2 = cinemas.cinemas();
+ BOOST_REQUIRE_EQUAL(check2.size(), 1U);
+ BOOST_CHECK(check2[0].second.name == name2);
+ BOOST_CHECK(check2[0].second.emails == emails2);
+ BOOST_CHECK_EQUAL(check2[0].second.notes, notes2);
+}
+
+
+BOOST_AUTO_TEST_CASE(update_cinema_test)
+{
+ auto const db = setup("update_cinema_test");
+
+ auto const name1 = "Bob's Zero-G Cinema";
+ auto const emails1 = vector<string>{"zerogbob@hotmail.com"};
+ auto const notes1 = "Nice enough place but the popcorn keeps floating away";
+ auto const utc_offset1 = dcp::UTCOffset{-4, -30};
+
+ auto const name2 = "Angie's Infinite-Screen Cinema";
+ auto const emails2 = vector<string>{"angie@infinitium.com", "projection-screen912341235@infinitium.com"};
+ auto const notes2 = "Nice enough place but it's very hard to find the right screen";
+ auto const utc_offset2 = dcp::UTCOffset{9, 0};
+
+ CinemaList cinemas(db);
+ auto const id = cinemas.add_cinema({name1, emails1, notes1, utc_offset1});
+ cinemas.add_cinema({name2, emails2, notes2, utc_offset2});
+
+ auto check = cinemas.cinemas();
+ BOOST_REQUIRE_EQUAL(check.size(), 2U);
+ /* Alphabetically ordered so first is 2 */
+ BOOST_CHECK_EQUAL(check[0].second.name, name2);
+ BOOST_CHECK(check[0].second.emails == emails2);
+ BOOST_CHECK_EQUAL(check[0].second.notes, notes2);
+ BOOST_CHECK(check[0].second.utc_offset == utc_offset2);
+ /* Then 1 */
+ BOOST_CHECK_EQUAL(check[1].second.name, name1);
+ BOOST_CHECK(check[1].second.emails == emails1);
+ BOOST_CHECK_EQUAL(check[1].second.notes, notes1);
+ BOOST_CHECK(check[1].second.utc_offset == utc_offset1);
+
+ cinemas.update_cinema(id, Cinema{name1, vector<string>{"bob@zerogkino.com"}, notes1, utc_offset1});
+
+ check = cinemas.cinemas();
+ BOOST_REQUIRE_EQUAL(check.size(), 2U);
+ BOOST_CHECK_EQUAL(check[0].second.name, name2);
+ BOOST_CHECK(check[0].second.emails == emails2);
+ BOOST_CHECK_EQUAL(check[0].second.notes, notes2);
+ BOOST_CHECK(check[0].second.utc_offset == utc_offset2);
+ BOOST_CHECK_EQUAL(check[1].second.name, name1);
+ BOOST_CHECK(check[1].second.emails == vector<string>{"bob@zerogkino.com"});
+ BOOST_CHECK_EQUAL(check[1].second.notes, notes1);
+ BOOST_CHECK(check[1].second.utc_offset == utc_offset1);
+}
+
+
+BOOST_AUTO_TEST_CASE(add_screen_test)
+{
+ auto const db = setup("add_screen_test");
+
+ CinemaList cinemas(db);
+ auto const cinema_id = cinemas.add_cinema({"Name", { "foo@bar.com" }, "", dcp::UTCOffset()});
+ auto const screen_id = cinemas.add_screen(
+ cinema_id,
+ dcpomatic::Screen(
+ "Screen 1",
+ "Smells of popcorn",
+ dcp::Certificate(dcp::file_to_string("test/data/cert.pem")),
+ string("test/data/cert.pem"),
+ vector<TrustedDevice>{}
+ ));
+
+ auto check = cinemas.screens(cinema_id);
+ BOOST_REQUIRE_EQUAL(check.size(), 1U);
+ BOOST_CHECK(check[0].first == screen_id);
+ BOOST_CHECK_EQUAL(check[0].second.name, "Screen 1");
+ BOOST_CHECK_EQUAL(check[0].second.notes, "Smells of popcorn");
+ BOOST_CHECK(check[0].second.recipient == dcp::Certificate(dcp::file_to_string("test/data/cert.pem")));
+ BOOST_CHECK(check[0].second.recipient_file == string("test/data/cert.pem"));
+}
+
+
+BOOST_AUTO_TEST_CASE(cinemas_list_copy_from_xml_test)
+{
+ Config::override_path = "build/test/cinemas_list_copy_config";
+ dcp::filesystem::remove_all(*Config::override_path);
+ dcp::filesystem::create_directories(*Config::override_path);
+ dcp::filesystem::copy_file("test/data/cinemas2.xml", *Config::override_path / "cinemas2.xml");
+ Config::drop();
+
+ CinemaList cinema_list;
+ cinema_list.read_legacy_file(Config::instance()->read_path("cinemas2.xml"));
+ auto cinemas = cinema_list.cinemas();
+ BOOST_REQUIRE_EQUAL(cinemas.size(), 3U);
+
+ auto cinema_iter = cinemas.begin();
+ BOOST_CHECK_EQUAL(cinema_iter->second.name, "Great");
+ BOOST_CHECK_EQUAL(cinema_iter->second.emails.size(), 1U);
+ BOOST_CHECK_EQUAL(cinema_iter->second.emails[0], "julie@tinyscreen.com");
+ BOOST_CHECK(cinema_iter->second.utc_offset == dcp::UTCOffset(1, 0));
+ ++cinema_iter;
+
+ BOOST_CHECK_EQUAL(cinema_iter->second.name, "classy joint");
+ BOOST_CHECK_EQUAL(cinema_iter->second.notes, "Can't stand this place");
+ ++cinema_iter;
+
+ BOOST_CHECK_EQUAL(cinema_iter->second.name, "stinking dump");
+ BOOST_CHECK_EQUAL(cinema_iter->second.emails.size(), 2U);
+ BOOST_CHECK_EQUAL(cinema_iter->second.emails[0], "bob@odourscreen.com");
+ BOOST_CHECK_EQUAL(cinema_iter->second.emails[1], "alice@whiff.com");
+ BOOST_CHECK_EQUAL(cinema_iter->second.notes, "Great cinema, smells of roses");
+ BOOST_CHECK(cinema_iter->second.utc_offset == dcp::UTCOffset(-7, 0));
+ auto screens = cinema_list.screens(cinema_iter->first);
+ BOOST_CHECK_EQUAL(screens.size(), 2U);
+ auto screen_iter = screens.begin();
+ BOOST_CHECK_EQUAL(screen_iter->second.name, "1");
+ BOOST_CHECK(screen_iter->second.recipient);
+ BOOST_CHECK_EQUAL(screen_iter->second.recipient->subject_dn_qualifier(), "CVsuuv9eYsQZSl8U4fDpvOmzZhI=");
+ ++screen_iter;
+ BOOST_CHECK_EQUAL(screen_iter->second.name, "2");
+ BOOST_CHECK(screen_iter->second.recipient);
+ BOOST_CHECK_EQUAL(screen_iter->second.recipient->subject_dn_qualifier(), "CVsuuv9eYsQZSl8U4fDpvOmzZhI=");
+}
+
diff --git a/test/config_test.cc b/test/config_test.cc
index d50c3d6f3..1c35f0a78 100644
--- a/test/config_test.cc
+++ b/test/config_test.cc
@@ -20,7 +20,12 @@
#include "lib/cinema.h"
+#include "lib/cinema_list.h"
#include "lib/config.h"
+#include "lib/dkdm_recipient.h"
+#include "lib/dkdm_recipient_list.h"
+#include "lib/unzipper.h"
+#include "lib/zipper.h"
#include "test.h"
#include <boost/test/unit_test.hpp>
#include <fstream>
@@ -178,19 +183,20 @@ BOOST_AUTO_TEST_CASE (config_upgrade_test1)
boost::filesystem::copy_file ("test/data/2.14.config.xml", dir / "config.xml");
boost::filesystem::copy_file ("test/data/2.14.cinemas.xml", dir / "cinemas.xml");
- Config::instance();
try {
- /* This will fail to write cinemas.xml since the link is to a non-existent directory */
- Config::instance()->write();
+ /* This will fail to read cinemas.xml since the link is to a non-existent directory */
+ Config::instance();
} catch (...) {}
+ Config::instance()->write();
+
check_xml (dir / "config.xml", "test/data/2.14.config.xml", {});
check_xml (dir / "cinemas.xml", "test/data/2.14.cinemas.xml", {});
#ifdef DCPOMATIC_WINDOWS
/* This file has the windows path for dkdm_recipients.xml (with backslashes) */
- check_xml(dir / "2.18" / "config.xml", "test/data/2.18.config.windows.xml", {});
+ check_xml(dir / "2.18" / "config.xml", "test/data/2.18.config.windows.sqlite.xml", {});
#else
- check_xml(dir / "2.18" / "config.xml", "test/data/2.18.config.xml", {});
+ check_xml(dir / "2.18" / "config.xml", "test/data/2.18.config.sqlite.xml", {});
#endif
/* cinemas.xml is not copied into 2.18 as its format has not changed */
BOOST_REQUIRE (!boost::filesystem::exists(dir / "2.18" / "cinemas.xml"));
@@ -214,12 +220,13 @@ BOOST_AUTO_TEST_CASE (config_upgrade_test2)
boost::filesystem::copy_file("test/data/2.16.config.xml", dir / "config.xml");
#endif
boost::filesystem::copy_file("test/data/2.14.cinemas.xml", dir / "cinemas.xml");
- Config::instance();
try {
- /* This will fail to write cinemas.xml since the link is to a non-existent directory */
- Config::instance()->write();
+ /* This will fail to read cinemas.xml since the link is to a non-existent directory */
+ Config::instance();
} catch (...) {}
+ Config::instance()->write();
+
check_xml(dir / "cinemas.xml", "test/data/2.14.cinemas.xml", {});
#ifdef DCPOMATIC_WINDOWS
/* This file has the windows path for dkdm_recipients.xml (with backslashes) */
@@ -246,16 +253,16 @@ BOOST_AUTO_TEST_CASE (config_keep_cinemas_if_making_new_config)
Config::instance()->write();
- Config::instance()->add_cinema(make_shared<Cinema>("My Great Cinema", vector<string>(), "", dcp::UTCOffset()));
- Config::instance()->write();
+ CinemaList cinemas;
+ cinemas.add_cinema({"My Great Cinema", {}, "", dcp::UTCOffset()});
- boost::filesystem::copy_file (dir / "cinemas.xml", dir / "backup_for_test.xml");
+ boost::filesystem::copy_file(dir / "cinemas.sqlite3", dir / "backup_for_test.sqlite3");
Config::drop ();
boost::filesystem::remove (dir / "2.18" / "config.xml");
Config::instance();
- check_text_file(dir / "backup_for_test.xml", dir / "cinemas.xml");
+ check_file(dir / "backup_for_test.sqlite3", dir / "cinemas.sqlite3");
}
@@ -271,11 +278,14 @@ BOOST_AUTO_TEST_CASE(keep_config_if_cinemas_fail_to_load)
boost::filesystem::create_directories(dir);
Config::instance()->write();
- auto const cinemas = dir / "cinemas.xml";
+ CinemaList cinema_list;
+ cinema_list.add_cinema(Cinema("Foo", {}, "Bar", dcp::UTCOffset()));
+
+ auto const cinemas = dir / "cinemas.sqlite3";
/* Back things up */
boost::filesystem::copy_file(dir / "2.18" / "config.xml", dir / "config_backup_for_test.xml");
- boost::filesystem::copy_file(cinemas, dir / "cinemas_backup_for_test.xml");
+ boost::filesystem::copy_file(cinemas, dir / "cinemas_backup_for_test.sqlite3");
/* Corrupt the cinemas */
Config::drop();
@@ -284,8 +294,241 @@ BOOST_AUTO_TEST_CASE(keep_config_if_cinemas_fail_to_load)
corrupt.close();
Config::instance();
- /* We should have a new cinemas.xml and the old config.xml */
+ /* We should have the old config.xml */
check_text_file(dir / "2.18" / "config.xml", dir / "config_backup_for_test.xml");
- check_text_file(cinemas, dir / "cinemas_backup_for_test.xml");
}
+
+BOOST_AUTO_TEST_CASE(read_cinemas_xml_and_write_sqlite)
+{
+ ConfigRestorer cr;
+
+ /* Set up a config with an XML cinemas file */
+ boost::filesystem::path dir = "build/test/read_cinemas_xml_and_write_sqlite";
+ boost::filesystem::remove_all(dir);
+ boost::filesystem::create_directories(dir);
+ boost::filesystem::create_directories(dir / "2.18");
+
+ boost::filesystem::copy_file("test/data/cinemas.xml", dir / "cinemas.xml");
+ boost::filesystem::copy_file("test/data/2.18.config.xml", dir / "2.18" / "config.xml");
+ {
+ Editor editor(dir / "2.18" / "config.xml");
+ editor.replace(
+ "/home/realldoesnt/exist/this/path/is/nonsense.xml",
+ boost::filesystem::canonical(dir / "cinemas.xml").string()
+ );
+ }
+
+ Config::override_path = dir;
+ Config::drop();
+
+ /* This should make a sqlite3 file containing the recipients from cinemas.xml */
+ Config::instance();
+
+ {
+ CinemaList test(dir / "cinemas.sqlite3");
+
+ /* The detailed creation of sqlite3 from XML is tested in cinema_list_test.cc */
+ auto cinemas = test.cinemas();
+ BOOST_REQUIRE_EQUAL(cinemas.size(), 3U);
+ BOOST_CHECK_EQUAL(cinemas[0].second.name, "Great");
+ BOOST_CHECK_EQUAL(cinemas[1].second.name, "classy joint");
+ BOOST_CHECK_EQUAL(cinemas[2].second.name, "stinking dump");
+
+ /* Add another recipient to the sqlite */
+ test.add_cinema({"The ol' 1-seater", {}, "Quiet but lonely", dcp::UTCOffset()});
+ }
+
+ /* Reload the config; the old XML should not clobber the new sqlite3 */
+ Config::drop();
+ Config::instance();
+
+ {
+ CinemaList test(dir / "cinemas.sqlite3");
+
+ auto cinemas = test.cinemas();
+ BOOST_REQUIRE_EQUAL(cinemas.size(), 4U);
+ BOOST_CHECK_EQUAL(cinemas[0].second.name, "Great");
+ BOOST_CHECK_EQUAL(cinemas[1].second.name, "The ol' 1-seater");
+ BOOST_CHECK_EQUAL(cinemas[2].second.name, "classy joint");
+ BOOST_CHECK_EQUAL(cinemas[3].second.name, "stinking dump");
+ }
+}
+
+
+BOOST_AUTO_TEST_CASE(read_dkdm_recipients_xml_and_write_sqlite)
+{
+ ConfigRestorer cr;
+
+ /* Set up a config with an XML cinemas file */
+ boost::filesystem::path dir = "build/test/read_dkdm_recipients_xml_and_write_sqlite";
+ boost::filesystem::remove_all(dir);
+ boost::filesystem::create_directories(dir);
+ boost::filesystem::create_directories(dir / "2.18");
+
+ boost::filesystem::copy_file("test/data/dkdm_recipients.xml", dir / "dkdm_recipients.xml");
+ boost::filesystem::copy_file("test/data/2.18.config.xml", dir / "2.18" / "config.xml");
+ {
+ Editor editor(dir / "2.18" / "config.xml");
+ editor.replace(
+ "build/test/config_upgrade_test/dkdm_recipients.xml",
+ boost::filesystem::canonical(dir / "dkdm_recipients.xml").string()
+ );
+ }
+
+ Config::override_path = dir;
+ Config::drop();
+
+ /* This should make a sqlite3 file containing the recipients from dkdm_recipients.xml */
+ Config::instance();
+
+ {
+ DKDMRecipientList test(dir / "dkdm_recipients.sqlite3");
+
+ /* The detailed creation of sqlite3 from XML is tested in dkdm_recipient_list_test.cc */
+ auto recipients = test.dkdm_recipients();
+ BOOST_REQUIRE_EQUAL(recipients.size(), 2U);
+ BOOST_CHECK_EQUAL(recipients[0].second.name, "Bob's Epics");
+ BOOST_CHECK_EQUAL(recipients[1].second.name, "Sharon's Shorts");
+
+ /* Add another recipient to the sqlite */
+ test.add_dkdm_recipient({"Carl's Classics", "Oldies but goodies", {}, {}});
+ }
+
+ /* Reload the config; the old XML should not clobber the new sqlite3 */
+ Config::drop();
+ Config::instance();
+
+ {
+ DKDMRecipientList test(dir / "dkdm_recipients.sqlite3");
+
+ auto recipients = test.dkdm_recipients();
+ BOOST_REQUIRE_EQUAL(recipients.size(), 3U);
+ BOOST_CHECK_EQUAL(recipients[0].second.name, "Bob's Epics");
+ BOOST_CHECK_EQUAL(recipients[1].second.name, "Carl's Classics");
+ BOOST_CHECK_EQUAL(recipients[2].second.name, "Sharon's Shorts");
+ }
+}
+
+
+BOOST_AUTO_TEST_CASE(save_config_as_zip_test)
+{
+ ConfigRestorer cr;
+
+ CinemaList cinemas;
+ cinemas.add_cinema({"My Great Cinema", {}, "", dcp::UTCOffset()});
+ DKDMRecipientList recipients;
+ recipients.add_dkdm_recipient({"Carl's Classics", "Oldies but goodies", {}, {}});
+
+ boost::filesystem::path const zip = "build/test/save.zip";
+ boost::system::error_code ec;
+ boost::filesystem::remove(zip, ec);
+ save_all_config_as_zip(zip);
+ Unzipper unzipper(zip);
+
+ BOOST_CHECK(unzipper.contains("config.xml"));
+ BOOST_CHECK(unzipper.contains("cinemas.sqlite3"));
+ BOOST_CHECK(unzipper.contains("dkdm_recipients.sqlite3"));
+}
+
+
+/** Load a config ZIP file, which contains an XML cinemas file, and ask to overwrite
+ * the existing cinemas file that we had.
+ */
+BOOST_AUTO_TEST_CASE(load_config_from_zip_with_only_xml_current)
+{
+ ConfigRestorer cr;
+
+ auto cinemas_file = Config::instance()->cinemas_file();
+
+ boost::filesystem::path const zip = "build/test/load.zip";
+ boost::system::error_code ec;
+ boost::filesystem::remove(zip, ec);
+
+ Zipper zipper(zip);
+ zipper.add(
+ "config.xml",
+ boost::algorithm::replace_all_copy(
+ dcp::file_to_string("test/data/2.18.config.xml"),
+ "/home/realldoesnt/exist/this/path/is/nonsense.xml",
+ ""
+ )
+ );
+
+ zipper.add("cinemas.xml", dcp::file_to_string("test/data/cinemas.xml"));
+ zipper.close();
+
+ Config::instance()->load_from_zip(zip, Config::CinemasAction::WRITE_TO_CURRENT_PATH);
+
+ CinemaList cinema_list(cinemas_file);
+ auto cinemas = cinema_list.cinemas();
+ BOOST_REQUIRE_EQUAL(cinemas.size(), 3U);
+ BOOST_CHECK_EQUAL(cinemas[0].second.name, "Great");
+ BOOST_CHECK_EQUAL(cinemas[1].second.name, "classy joint");
+ BOOST_CHECK_EQUAL(cinemas[2].second.name, "stinking dump");
+}
+
+
+/** Load a config ZIP file, which contains an XML cinemas file, and ask to write it to
+ * the location specified by the zipped config.xml.
+ */
+BOOST_AUTO_TEST_CASE(load_config_from_zip_with_only_xml_zip)
+{
+ ConfigRestorer cr;
+
+ boost::filesystem::path const zip = "build/test/load.zip";
+ boost::system::error_code ec;
+ boost::filesystem::remove(zip, ec);
+
+ Zipper zipper(zip);
+ zipper.add(
+ "config.xml",
+ boost::algorithm::replace_all_copy(
+ dcp::file_to_string("test/data/2.18.config.xml"),
+ "/home/realldoesnt/exist/this/path/is/nonsense.xml",
+ "build/test/hide/it/here/cinemas.sqlite3"
+ )
+ );
+
+ zipper.add("cinemas.xml", dcp::file_to_string("test/data/cinemas.xml"));
+ zipper.close();
+
+ Config::instance()->load_from_zip(zip, Config::CinemasAction::WRITE_TO_PATH_IN_ZIPPED_CONFIG);
+
+ CinemaList cinema_list("build/test/hide/it/here/cinemas.sqlite3");
+ auto cinemas = cinema_list.cinemas();
+ BOOST_REQUIRE_EQUAL(cinemas.size(), 3U);
+ BOOST_CHECK_EQUAL(cinemas[0].second.name, "Great");
+ BOOST_CHECK_EQUAL(cinemas[1].second.name, "classy joint");
+ BOOST_CHECK_EQUAL(cinemas[2].second.name, "stinking dump");
+}
+
+
+/** Load a config ZIP file, which contains an XML cinemas file, and ask to ignore it */
+BOOST_AUTO_TEST_CASE(load_config_from_zip_with_only_xml_ignore)
+{
+ ConfigRestorer cr;
+
+ boost::filesystem::path const zip = "build/test/load.zip";
+ boost::system::error_code ec;
+ boost::filesystem::remove(zip, ec);
+
+ Zipper zipper(zip);
+ zipper.add(
+ "config.xml",
+ boost::algorithm::replace_all_copy(
+ dcp::file_to_string("test/data/2.18.config.xml"),
+ "/home/realldoesnt/exist/this/path/is/nonsense.xml",
+ "build/test/hide/it/here/cinemas.sqlite3"
+ )
+ );
+
+ zipper.add("cinemas.xml", "<?xml version=\"1.0\" encoding=\"UTF-8\"?><Cinemas/>");
+ zipper.close();
+
+ Config::instance()->load_from_zip(zip, Config::CinemasAction::IGNORE);
+
+ CinemaList cinema_list("build/test/hide/it/here/cinemas.sqlite3");
+ auto cinemas = cinema_list.cinemas();
+ BOOST_CHECK(!cinemas.empty());
+}
diff --git a/test/data b/test/data
-Subproject 351419eebadc7d0a9aafc84f45e77218783e4b3
+Subproject b4fe926644bb49e442a3a920cb4601be8959bfb
diff --git a/test/dkdm_recipient_list_test.cc b/test/dkdm_recipient_list_test.cc
new file mode 100644
index 000000000..20f669e76
--- /dev/null
+++ b/test/dkdm_recipient_list_test.cc
@@ -0,0 +1,56 @@
+/*
+ Copyright (C) 2024 Carl Hetherington <cth@carlh.net>
+
+ This file is part of DCP-o-matic.
+
+ DCP-o-matic is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ DCP-o-matic is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with DCP-o-matic. If not, see <http://www.gnu.org/licenses/>.
+
+*/
+
+
+#include "lib/config.h"
+#include "lib/dkdm_recipient.h"
+#include "lib/dkdm_recipient_list.h"
+#include <dcp/filesystem.h>
+#include <boost/test/unit_test.hpp>
+
+
+BOOST_AUTO_TEST_CASE(dkdm_receipient_list_copy_from_xml_test)
+{
+ Config::override_path = "build/test/dkdm_recipient_list_copy_config";
+ dcp::filesystem::remove_all(*Config::override_path);
+ dcp::filesystem::create_directories(*Config::override_path);
+ dcp::filesystem::copy_file("test/data/dkdm_recipients.xml", *Config::override_path / "dkdm_recipients.xml");
+ Config::drop();
+
+ DKDMRecipientList dkdm_recipient_list;
+ dkdm_recipient_list.read_legacy_file(Config::instance()->read_path("dkdm_recipients.xml"));
+ auto dkdm_recipients = dkdm_recipient_list.dkdm_recipients();
+ BOOST_REQUIRE_EQUAL(dkdm_recipients.size(), 2U);
+
+ auto dkdm_recipient_iter = dkdm_recipients.begin();
+ BOOST_CHECK_EQUAL(dkdm_recipient_iter->second.name, "Bob's Epics");
+ BOOST_CHECK_EQUAL(dkdm_recipient_iter->second.emails.size(), 2U);
+ BOOST_CHECK_EQUAL(dkdm_recipient_iter->second.emails[0], "epicbob@gmail.com");
+ BOOST_CHECK_EQUAL(dkdm_recipient_iter->second.emails[1], "boblikesemlong@cinema-bob.com");
+ BOOST_CHECK_EQUAL(dkdm_recipient_iter->second.recipient->subject_dn_qualifier(), "r5/Q5f3UTm7qzoF5QzNZP6aEuvI=");
+ ++dkdm_recipient_iter;
+
+ BOOST_CHECK_EQUAL(dkdm_recipient_iter->second.name, "Sharon's Shorts");
+ BOOST_CHECK_EQUAL(dkdm_recipient_iter->second.notes, "Even if it sucks, at least it's over quickly");
+ BOOST_CHECK_EQUAL(dkdm_recipient_iter->second.recipient->subject_dn_qualifier(), "FHerM3Us/DWuqD1MnztStSlFJO0=");
+ ++dkdm_recipient_iter;
+}
+
+
diff --git a/test/kdm_cli_test.cc b/test/kdm_cli_test.cc
index 1c590cdf7..3fd20d478 100644
--- a/test/kdm_cli_test.cc
+++ b/test/kdm_cli_test.cc
@@ -20,6 +20,7 @@
#include "lib/cinema.h"
+#include "lib/cinema_list.h"
#include "lib/config.h"
#include "lib/content_factory.h"
#include "lib/cross.h"
@@ -154,16 +155,16 @@ setup_test_config()
auto config = Config::instance();
auto const cert = dcp::Certificate(dcp::file_to_string("test/data/cert.pem"));
- auto cinema_a = std::make_shared<Cinema>("Dean's Screens", vector<string>(), "", dcp::UTCOffset());
- cinema_a->add_screen(std::make_shared<dcpomatic::Screen>("Screen 1", "", cert, boost::none, std::vector<TrustedDevice>()));
- cinema_a->add_screen(std::make_shared<dcpomatic::Screen>("Screen 2", "", cert, boost::none, std::vector<TrustedDevice>()));
- cinema_a->add_screen(std::make_shared<dcpomatic::Screen>("Screen 3", "", cert, boost::none, std::vector<TrustedDevice>()));
- config->add_cinema(cinema_a);
+ CinemaList cinemas(config->cinemas_file());
- auto cinema_b = std::make_shared<Cinema>("Floyd's Celluloid", vector<string>(), "", dcp::UTCOffset());
- cinema_b->add_screen(std::make_shared<dcpomatic::Screen>("Foo", "", cert, boost::none, std::vector<TrustedDevice>()));
- cinema_b->add_screen(std::make_shared<dcpomatic::Screen>("Bar", "", cert, boost::none, std::vector<TrustedDevice>()));
- config->add_cinema(cinema_b);
+ auto cinema_a = cinemas.add_cinema({"Dean's Screens", {}, "", dcp::UTCOffset()});
+ cinemas.add_screen(cinema_a, {"Screen 1", "", cert, boost::none, {}});
+ cinemas.add_screen(cinema_a, {"Screen 2", "", cert, boost::none, {}});
+ cinemas.add_screen(cinema_a, {"Screen 3", "", cert, boost::none, {}});
+
+ auto cinema_b = cinemas.add_cinema({"Floyd's Celluloid", {}, "", dcp::UTCOffset()});
+ cinemas.add_screen(cinema_b, {"Foo", "", cert, boost::none, std::vector<TrustedDevice>()});
+ cinemas.add_screen(cinema_b, {"Bar", "", cert, boost::none, std::vector<TrustedDevice>()});
}
@@ -250,7 +251,7 @@ BOOST_AUTO_TEST_CASE(kdm_cli_specify_cinemas_file)
vector<string> args = {
"kdm_cli",
"--cinemas-file",
- "test/data/cinemas.xml",
+ "test/data/cinemas.sqlite3",
"list-cinemas"
};
@@ -259,9 +260,9 @@ BOOST_AUTO_TEST_CASE(kdm_cli_specify_cinemas_file)
BOOST_CHECK(!error);
BOOST_REQUIRE_EQUAL(output.size(), 3U);
- BOOST_CHECK_EQUAL(output[0], "stinking dump ()");
+ BOOST_CHECK_EQUAL(output[0], "Great (julie@tinyscreen.com)");
BOOST_CHECK_EQUAL(output[1], "classy joint ()");
- BOOST_CHECK_EQUAL(output[2], "Great ()");
+ BOOST_CHECK_EQUAL(output[2], "stinking dump (bob@odourscreen.com, alice@whiff.com)");
}
diff --git a/test/kdm_naming_test.cc b/test/kdm_naming_test.cc
index f73e4295e..c5c7c2678 100644
--- a/test/kdm_naming_test.cc
+++ b/test/kdm_naming_test.cc
@@ -20,6 +20,7 @@
#include "lib/cinema.h"
+#include "lib/cinema_list.h"
#include "lib/config.h"
#include "lib/content_factory.h"
#include "lib/film.h"
@@ -32,6 +33,7 @@
using std::dynamic_pointer_cast;
using std::list;
using std::make_shared;
+using std::pair;
using std::shared_ptr;
using std::string;
using std::vector;
@@ -46,34 +48,40 @@ confirm_overwrite (boost::filesystem::path)
}
-static shared_ptr<dcpomatic::Screen> cinema_a_screen_1;
-static shared_ptr<dcpomatic::Screen> cinema_a_screen_2;
-static shared_ptr<dcpomatic::Screen> cinema_b_screen_x;
-static shared_ptr<dcpomatic::Screen> cinema_b_screen_y;
-static shared_ptr<dcpomatic::Screen> cinema_b_screen_z;
+struct Context
+{
+ Context()
+ {
+ CinemaList cinemas;
+
+ auto crypt_cert = Config::instance()->decryption_chain()->leaf();
+
+ cinema_a = cinemas.add_cinema({"Cinema A", {}, "", dcp::UTCOffset(4, 30)});
+ cinema_a_screen_1 = cinemas.add_screen(cinema_a, {"Screen 1", "", crypt_cert, boost::none, {}});
+ cinema_a_screen_2 = cinemas.add_screen(cinema_a, {"Screen 2", "", crypt_cert, boost::none, {}});
+
+ cinema_b = cinemas.add_cinema({"Cinema B", {}, "", dcp::UTCOffset(-1, 0)});
+ cinema_b_screen_x = cinemas.add_screen(cinema_b, {"Screen X", "", crypt_cert, boost::none, {}});
+ cinema_b_screen_y = cinemas.add_screen(cinema_b, {"Screen Y", "", crypt_cert, boost::none, {}});
+ cinema_b_screen_z = cinemas.add_screen(cinema_b, {"Screen Z", "", crypt_cert, boost::none, {}});
+ }
+
+ CinemaID cinema_a = 0;
+ CinemaID cinema_b = 0;
+ ScreenID cinema_a_screen_1 = 0;
+ ScreenID cinema_a_screen_2 = 0;
+ ScreenID cinema_b_screen_x = 0;
+ ScreenID cinema_b_screen_y = 0;
+ ScreenID cinema_b_screen_z = 0;
+};
BOOST_AUTO_TEST_CASE (single_kdm_naming_test)
{
auto c = Config::instance();
- auto crypt_cert = c->decryption_chain()->leaf();
-
- auto cinema_a = make_shared<Cinema>("Cinema A", vector<string>(), "", dcp::UTCOffset{4, 30});
- cinema_a_screen_1 = std::make_shared<dcpomatic::Screen>("Screen 1", "", crypt_cert, boost::none, vector<TrustedDevice>());
- cinema_a->add_screen (cinema_a_screen_1);
- cinema_a_screen_2 = std::make_shared<dcpomatic::Screen>("Screen 2", "", crypt_cert, boost::none, vector<TrustedDevice>());
- cinema_a->add_screen (cinema_a_screen_2);
- c->add_cinema (cinema_a);
-
- auto cinema_b = make_shared<Cinema>("Cinema B", vector<string>(), "", dcp::UTCOffset{-1, 0});
- cinema_b_screen_x = std::make_shared<dcpomatic::Screen>("Screen X", "", crypt_cert, boost::none, vector<TrustedDevice>());
- cinema_b->add_screen (cinema_b_screen_x);
- cinema_b_screen_y = std::make_shared<dcpomatic::Screen>("Screen Y", "", crypt_cert, boost::none, vector<TrustedDevice>());
- cinema_b->add_screen (cinema_b_screen_y);
- cinema_b_screen_z = std::make_shared<dcpomatic::Screen>("Screen Z", "", crypt_cert, boost::none, vector<TrustedDevice>());
- cinema_b->add_screen (cinema_b_screen_z);
- c->add_cinema (cinema_a);
+ Context context;
+ CinemaList cinemas;
/* Film */
boost::filesystem::remove_all ("build/test/single_kdm_naming_test");
@@ -101,7 +109,9 @@ BOOST_AUTO_TEST_CASE (single_kdm_naming_test)
};
auto kdm = kdm_for_screen (
make_kdm,
- cinema_a_screen_1,
+ context.cinema_a,
+ *cinemas.cinema(context.cinema_a),
+ *cinemas.screen(context.cinema_a_screen_1),
from,
until,
dcp::Formulation::MODIFIED_TRANSITIONAL_1,
@@ -128,10 +138,13 @@ BOOST_AUTO_TEST_CASE (single_kdm_naming_test)
}
-BOOST_AUTO_TEST_CASE (directory_kdm_naming_test, * boost::unit_test::depends_on("single_kdm_naming_test"))
+BOOST_AUTO_TEST_CASE(directory_kdm_naming_test)
{
using boost::filesystem::path;
+ Context context;
+ CinemaList cinemas;
+
/* Film */
boost::filesystem::remove_all ("build/test/directory_kdm_naming_test");
auto film = new_test_film2 (
@@ -152,8 +165,11 @@ BOOST_AUTO_TEST_CASE (directory_kdm_naming_test, * boost::unit_test::depends_on(
dcp::LocalTime until (sign_cert.not_after());
until.add_months (-2);
- vector<shared_ptr<dcpomatic::Screen>> screens = {
- cinema_a_screen_2, cinema_b_screen_x, cinema_a_screen_1, (cinema_b_screen_z)
+ vector<pair<CinemaID, ScreenID>> screens = {
+ { context.cinema_a, context.cinema_a_screen_2 },
+ { context.cinema_b, context.cinema_b_screen_x },
+ { context.cinema_a, context.cinema_a_screen_1 },
+ { context.cinema_b, context.cinema_b_screen_z }
};
auto const cpl = cpls.front().cpl_file;
@@ -166,10 +182,12 @@ BOOST_AUTO_TEST_CASE (directory_kdm_naming_test, * boost::unit_test::depends_on(
return film->make_kdm(cpls.front().cpl_file, begin, end);
};
- for (auto i: screens) {
+ for (auto screen: screens) {
auto kdm = kdm_for_screen (
make_kdm,
- i,
+ screen.first,
+ *cinemas.cinema(screen.first),
+ *cinemas.screen(screen.second),
from,
until,
dcp::Formulation::MODIFIED_TRANSITIONAL_1,
diff --git a/test/recover_test.cc b/test/recover_test.cc
index 01b71a05e..696a2c36a 100644
--- a/test/recover_test.cc
+++ b/test/recover_test.cc
@@ -63,6 +63,7 @@ BOOST_AUTO_TEST_CASE (recover_test_2d)
film->set_dcp_content_type (DCPContentType::from_isdcf_name ("FTR"));
film->set_container (Ratio::from_id ("185"));
film->set_name ("recover_test");
+ film->set_video_bit_rate(VideoEncoding::JPEG2000, 100000000);
auto content = make_shared<FFmpegContent>("test/data/count300bd24.m2ts");
film->examine_and_add_content (content);
@@ -110,6 +111,7 @@ BOOST_AUTO_TEST_CASE (recover_test_3d, * boost::unit_test::depends_on("recover_t
film->set_container (Ratio::from_id ("185"));
film->set_name ("recover_test");
film->set_three_d (true);
+ film->set_video_bit_rate(VideoEncoding::JPEG2000, 100000000);
auto content = make_shared<ImageContent>("test/data/3d_test");
content->video->set_frame_type (VideoFrameType::THREE_D_LEFT_RIGHT);
@@ -154,6 +156,7 @@ BOOST_AUTO_TEST_CASE (recover_test_2d_encrypted, * boost::unit_test::depends_on(
film->set_name ("recover_test");
film->set_encrypted (true);
film->_key = dcp::Key("eafcb91c9f5472edf01f3a2404c57258");
+ film->set_video_bit_rate(VideoEncoding::JPEG2000, 100000000);
auto content = make_shared<FFmpegContent>("test/data/count300bd24.m2ts");
film->examine_and_add_content (content);
diff --git a/test/test.cc b/test/test.cc
index ddd3d26f0..d214f1d39 100644
--- a/test/test.cc
+++ b/test/test.cc
@@ -138,7 +138,8 @@ setup_test_config ()
decryption->set_key(dcp::file_to_string("test/data/decryption_key"));
Config::instance()->set_decryption_chain (decryption);
Config::instance()->set_dcp_asset_filename_format(dcp::NameFormat("%t"));
- Config::instance()->set_cinemas_file("test/data/empty_cinemas.xml");
+ Config::instance()->set_cinemas_file("build/test/cinemas.sqlite3");
+ Config::instance()->set_dkdm_recipients_file("build/test/dkdm_recipients.sqlite3");
}
diff --git a/test/wscript b/test/wscript
index 3acca09e8..7555f76db 100644
--- a/test/wscript
+++ b/test/wscript
@@ -37,7 +37,7 @@ def build(bld):
obj.name = 'unit-tests'
obj.uselib = 'BOOST_TEST BOOST_THREAD BOOST_FILESYSTEM BOOST_DATETIME SNDFILE SAMPLERATE DCP FONTCONFIG CAIROMM PANGOMM XMLPP '
obj.uselib += 'AVFORMAT AVFILTER AVCODEC AVUTIL SWSCALE SWRESAMPLE POSTPROC CXML SUB GLIB CURL SSH XMLSEC BOOST_REGEX ICU NETTLE PNG JPEG '
- obj.uselib += 'LEQM_NRT ZIP '
+ obj.uselib += 'LEQM_NRT ZIP SQLITE3 '
if bld.env.TARGET_WINDOWS_64 or bld.env.TARGET_WINDOWS_32:
obj.uselib += 'WINSOCK2 DBGHELP SHLWAPI MSWSOCK BOOST_LOCALE '
if bld.env.TARGET_LINUX:
@@ -60,6 +60,7 @@ def build(bld):
burnt_subtitle_test.cc
butler_test.cc
bv20_test.cc
+ cinema_list_test.cc
cinema_sound_processor_test.cc
client_server_test.cc
closed_caption_test.cc
@@ -78,6 +79,7 @@ def build(bld):
dcp_playback_test.cc
dcp_subtitle_test.cc
digest_test.cc
+ dkdm_recipient_list_test.cc
empty_caption_test.cc
empty_test.cc
encryption_test.cc