diff --git a/include/loot/database_interface.h b/include/loot/database_interface.h index f45752e5..e91f98f9 100644 --- a/include/loot/database_interface.h +++ b/include/loot/database_interface.h @@ -28,8 +28,10 @@ #include #include "loot/enum/language_code.h" -#include "loot/struct/masterlist_info.h" #include "loot/enum/plugin_cleanliness.h" +#include "loot/metadata/message.h" +#include "loot/metadata/plugin_metadata.h" +#include "loot/struct/masterlist_info.h" #include "loot/struct/plugin_tags.h" #include "loot/struct/simple_message.h" @@ -38,7 +40,7 @@ namespace loot { class DatabaseInterface { public: /** - * @name Data Loading + * @name Data Reading & Writing * @{ */ @@ -64,6 +66,30 @@ public: */ virtual void EvalLists() = 0; + /** + * Writes a metadata file containing all loaded user-added metadata. + * @param outputFile + * The path to which the file shall be written. + * @param overwrite + * If `false` and `outputFile` already exists, no data will be + * written. Otherwise, data will be written. + */ + virtual void WriteUserMetadata(const std::string& outputFile, + const bool overwrite) = 0; + + /** + * @brief Writes a minimal metadata file that only contains plugins with + * Bash Tag suggestions and/or dirty info, plus the suggestions and + * info themselves. + * @param outputFile + * The path to which the file shall be written. + * @param overwrite + * If `false` and `outputFile` already exists, no data will be + * written. Otherwise, data will be written. + */ + virtual void WriteMinimalList(const std::string& outputFile, + const bool overwrite) = 0; + /** * @} * @name Sorting @@ -150,6 +176,26 @@ public: virtual MasterlistInfo GetMasterlistRevision(const std::string& masterlist_path, const bool get_short_id) = 0; + /** + * @} + * @name Non-plugin Data Access + * @{ + */ + + /** + * @brief Gets the Bash Tags that are listed in the loaded metadata lists. + * @details Bash Tag suggestions can include plugins not in this list. + * @returns A set of Bash Tag names. + */ + virtual std::set GetKnownBashTags() = 0; + + /** + * @brief Get all general messages listen in the loaded metadata lists. + * @returns A vector of messages supplied in the metadata lists but not + * attached to any particular plugin. + */ + virtual std::vector GetGeneralMessages() = 0; + /** * @} * @name Plugin Data Access @@ -157,6 +203,51 @@ public: */ /** + * @brief Get all a plugin's loaded metadata. + * @param plugin + * The filename of the plugin to look up metadata for. + * @returns A PluginMetadata object containing all the plugin's metadata. + * If the plugin has no metadata, PluginMetadata.IsNameOnly() + * will return true. + */ + virtual PluginMetadata GetPluginMetadata(const std::string& plugin) = 0; + + /** + * @brief Get a plugin's metadata loaded from the given userlist. + * @param plugin + * The filename of the plugin to look up user-added metadata for. + * @returns A PluginMetadata object containing the plugin's user-added + * metadata. If the plugin has no metadata, + * PluginMetadata.IsNameOnly() will return true. + */ + virtual PluginMetadata GetPluginUserMetadata(const std::string& plugin) = 0; + + /** + * @brief Sets a plugin's user metadata, overwriting any existing user + * metadata. + * @param plugin + * The user metadata you want to set, with plugin.Name() being the + * filename of the plugin the metadata is for. + */ + virtual void SetPluginUserMetadata(const PluginMetadata& pluginMetadata) = 0; + + /** + * @brief Discards all loaded user metadata for the plugin with the given + * filename. + * @param plugin + * The filename of the plugin for which all user-added metadata + * should be deleted. + */ + virtual void DiscardPluginUserMetadata(const std::string& plugin) = 0; + + /** + * @brief Discards all loaded user metadata for all plugins, and any user-added + * general messages and known bash tags. + */ + virtual void DiscardAllUserMetadata() = 0; + + /** + * @deprecated * @brief Outputs the Bash Tags suggested for addition and removal by the * database for the given plugin. * @param plugin @@ -166,6 +257,7 @@ public: virtual PluginTags GetPluginTags(const std::string& plugin) = 0; /** + * @deprecated * @brief Outputs the messages associated with the given plugin in the * database. * @param plugin @@ -180,6 +272,7 @@ public: const LanguageCode language) = 0; /** + * @deprecated * @brief Determines the database's knowledge of a plugin's cleanliness. * @details Outputs whether the plugin should be cleaned or not, or if * no data is available. The mechanism used to determine that @@ -194,25 +287,6 @@ public: */ virtual PluginCleanliness GetPluginCleanliness(const std::string& plugin) = 0; - /** - * @} - * @name Miscellaneous - * @{ - */ - - /** - * @brief Writes a minimal metadata file that only contains plugins with - * Bash Tag suggestions and/or dirty info, plus the suggestions and - * info themselves. - * @param outputFile - * The path to which the file shall be written. - * @param overwrite - * If `false` and `outputFile` already exists, no data will be - * written. Otherwise, data will be written. - */ - virtual void WriteMinimalList(const std::string& outputFile, - const bool overwrite) = 0; - /** @} */ }; } diff --git a/src/api/api_database.cpp b/src/api/api_database.cpp index b6d27065..b439f70b 100644 --- a/src/api/api_database.cpp +++ b/src/api/api_database.cpp @@ -84,6 +84,16 @@ void ApiDatabase::EvalLists() { game_.GetUserlist() = userTemp; } +void ApiDatabase::WriteUserMetadata(const std::string& outputFile, const bool overwrite) { + if (!boost::filesystem::exists(boost::filesystem::path(outputFile).parent_path())) + throw std::invalid_argument("Output directory does not exist."); + + if (boost::filesystem::exists(outputFile) && !overwrite) + throw FileAccessError("Output file exists but overwrite is not set to true."); + + game_.GetUserlist().Save(outputFile); +} + void ApiDatabase::IdentifyMainMasterFile(const std::string& masterFile) { masterFile_ = masterFile; } @@ -123,6 +133,52 @@ MasterlistInfo ApiDatabase::GetMasterlistRevision(const std::string& masterlistP return Masterlist::GetInfo(masterlistPath, getShortID); } +std::set ApiDatabase::GetKnownBashTags() { + auto masterlistTags = game_.GetMasterlist().BashTags(); + auto userlistTags = game_.GetUserlist().BashTags(); + + if (!userlistTags.empty()) { + masterlistTags.insert(std::begin(userlistTags), std::end(userlistTags)); + } + + return masterlistTags; +} + +std::vector ApiDatabase::GetGeneralMessages() { + auto masterlistMessages = game_.GetMasterlist().Messages(); + auto userlistMessages = game_.GetUserlist().Messages(); + + if (!userlistMessages.empty()) { + masterlistMessages.insert(std::end(masterlistMessages), std::begin(userlistMessages), std::end(userlistMessages)); + } + + return masterlistMessages; +} + +PluginMetadata ApiDatabase::GetPluginMetadata(const std::string& plugin) { + PluginMetadata metadata = game_.GetMasterlist().FindPlugin(plugin); + metadata.MergeMetadata(game_.GetUserlist().FindPlugin(plugin)); + + return metadata; +} + +PluginMetadata ApiDatabase::GetPluginUserMetadata(const std::string& plugin) { + return game_.GetUserlist().FindPlugin(plugin); +} + +void ApiDatabase::SetPluginUserMetadata(const PluginMetadata& pluginMetadata) { + game_.GetUserlist().ErasePlugin(pluginMetadata); + game_.GetUserlist().AddPlugin(pluginMetadata); +} + +void ApiDatabase::DiscardPluginUserMetadata(const std::string& plugin) { + game_.GetUserlist().ErasePlugin(plugin); +} + +void ApiDatabase::DiscardAllUserMetadata() { + game_.GetUserlist().Clear(); +} + ////////////////////////// // DB Access Functions ////////////////////////// diff --git a/src/api/api_database.h b/src/api/api_database.h index 25d577bf..cf42a3a5 100644 --- a/src/api/api_database.h +++ b/src/api/api_database.h @@ -43,6 +43,12 @@ struct ApiDatabase : public DatabaseInterface { void EvalLists(); + void WriteUserMetadata(const std::string& outputFile, + const bool overwrite); + + void WriteMinimalList(const std::string& outputFile, + const bool overwrite); + void IdentifyMainMasterFile(const std::string& masterFile); std::vector SortPlugins(const std::vector& plugins); @@ -54,15 +60,26 @@ struct ApiDatabase : public DatabaseInterface { MasterlistInfo GetMasterlistRevision(const std::string& masterlist_path, const bool get_short_id); + std::set GetKnownBashTags(); + + std::vector GetGeneralMessages(); + + PluginMetadata GetPluginMetadata(const std::string& plugin); + + PluginMetadata GetPluginUserMetadata(const std::string& plugin); + + void SetPluginUserMetadata(const PluginMetadata& pluginMetadata); + + void DiscardPluginUserMetadata(const std::string& plugin); + + void DiscardAllUserMetadata(); + PluginTags GetPluginTags(const std::string& plugin); std::vector GetPluginMessages(const std::string& plugin, const LanguageCode language); PluginCleanliness GetPluginCleanliness(const std::string& plugin); - - void WriteMinimalList(const std::string& outputFile, - const bool overwrite); private: Game game_; diff --git a/src/backend/metadata_list.cpp b/src/backend/metadata_list.cpp index 43a5df12..41865d6f 100644 --- a/src/backend/metadata_list.cpp +++ b/src/backend/metadata_list.cpp @@ -78,6 +78,9 @@ void MetadataList::Save(const boost::filesystem::path& filepath) { << YAML::EndMap; boost::filesystem::ofstream uout(filepath); + if (uout.fail()) + throw FileAccessError("Couldn't open output file."); + uout << yout.c_str(); uout.close(); } diff --git a/src/tests/api/api_game_operations_test.h b/src/tests/api/api_game_operations_test.h index c10fcff6..4a0d1228 100644 --- a/src/tests/api/api_game_operations_test.h +++ b/src/tests/api/api_game_operations_test.h @@ -38,7 +38,8 @@ protected: masterlistPath(localPath / "masterlist.yaml"), noteMessage("Do not clean ITM records, they are intentional and required for the mod to function."), warningMessage("Check you are using v2+. If not, Update. v1 has a severe bug with the Mystic Emporium disappearing."), - errorMessage("Obsolete. Remove this and install Enhanced Weather.") {} + errorMessage("Obsolete. Remove this and install Enhanced Weather."), + generalMasterlistMessage("A general masterlist message.") {} virtual void SetUp() { CommonGameTestFixture::SetUp(); @@ -60,6 +61,12 @@ protected: boost::filesystem::ofstream masterlist(masterlistPath); masterlist + << "bash_tags:" << endl + << " - Actors.ACBS" << endl + << " - C.Climate" << endl + << "globals:" << endl + << " - type: say" << endl + << " content: '" << generalMasterlistMessage << "'" << endl << "plugins:" << endl << " - name: " << blankEsm << endl << " after:" << endl @@ -111,6 +118,7 @@ protected: const std::string noteMessage; const std::string warningMessage; const std::string errorMessage; + const std::string generalMasterlistMessage; }; } } diff --git a/src/tests/api/database_interface_test.h b/src/tests/api/database_interface_test.h index 71cd887a..d0446ee1 100644 --- a/src/tests/api/database_interface_test.h +++ b/src/tests/api/database_interface_test.h @@ -37,7 +37,8 @@ protected: userlistPath_(localPath / "userlist.yaml"), url_("https://github.com/loot/testing-metadata.git"), branch_("master"), - minimalOutputPath_(localPath / "minimal.yml") {} + minimalOutputPath_(localPath / "minimal.yml"), + generalUserlistMessage("A general userlist message.") {} void SetUp() { ApiGameOperationsTest::SetUp(); @@ -83,10 +84,41 @@ protected: return expectedContent.str(); } + std::string GetFileContent(const boost::filesystem::path& file) { + boost::filesystem::ifstream stream(file); + std::stringstream content; + content << stream.rdbuf(); + + return content.str(); + } + + void GenerateUserlist() { + using std::endl; + + boost::filesystem::ofstream userlist(userlistPath_); + userlist + << "bash_tags:" << endl + << " - RaceRelations" << endl + << " - C.Lighting" << endl + << "globals:" << endl + << " - type: say" << endl + << " content: '" << generalUserlistMessage << "'" << endl + << "plugins:" << endl + << " - name: " << blankEsm << endl + << " after:" << endl + << " - " << blankDifferentEsm << endl + << " - name: " << blankDifferentEsp << endl + << " inc:" << endl + << " - " << blankEsp << endl; + + userlist.close(); + } + const boost::filesystem::path userlistPath_; const boost::filesystem::path minimalOutputPath_; const std::string url_; const std::string branch_; + const std::string generalUserlistMessage; }; // Pass an empty first argument, as it's a prefix for the test instantation, @@ -134,6 +166,62 @@ TEST_P(DatabaseInterfaceTest, evalListsShouldReturnOKForAllLanguagesWithAMasterl EXPECT_NO_THROW(db_->EvalLists()); } +TEST_P(DatabaseInterfaceTest, writeUserMetadataShouldThrowIfTheFileAlreadyExistsAndTheOverwriteArgumentIsFalse) { + ASSERT_NO_THROW(db_->WriteUserMetadata(minimalOutputPath_.string(), false)); + ASSERT_TRUE(boost::filesystem::exists(minimalOutputPath_)); + + EXPECT_THROW(db_->WriteUserMetadata(minimalOutputPath_.string(), false), FileAccessError); +} + +TEST_P(DatabaseInterfaceTest, writeUserMetadataShouldReturnOkAndWriteToFileIfTheArgumentsAreValidAndTheOverwriteArgumentIsTrue) { + EXPECT_NO_THROW(db_->WriteUserMetadata(minimalOutputPath_.string(), true)); + EXPECT_TRUE(boost::filesystem::exists(minimalOutputPath_)); +} + +TEST_P(DatabaseInterfaceTest, writeUserMetadataShouldReturnOkIfTheFileAlreadyExistsAndTheOverwriteArgumentIsTrue) { + ASSERT_NO_THROW(db_->WriteUserMetadata(minimalOutputPath_.string(), false)); + ASSERT_TRUE(boost::filesystem::exists(minimalOutputPath_)); + + EXPECT_NO_THROW(db_->WriteUserMetadata(minimalOutputPath_.string(), true)); +} + +TEST_P(DatabaseInterfaceTest, writeUserMetadataShouldThrowIfPathGivenExistsAndIsReadOnly) { + ASSERT_NO_THROW(db_->WriteUserMetadata(minimalOutputPath_.string(), false)); + ASSERT_TRUE(boost::filesystem::exists(minimalOutputPath_)); + + boost::filesystem::permissions(minimalOutputPath_, + boost::filesystem::perms::remove_perms + | boost::filesystem::perms::owner_write); + + EXPECT_THROW(db_->WriteUserMetadata(minimalOutputPath_.string(), true), FileAccessError); +} + +TEST_P(DatabaseInterfaceTest, writeUserMetadataShouldShouldNotWriteMasterlistMetadata) { + ASSERT_NO_THROW(GenerateMasterlist()); + ASSERT_NO_THROW(db_->LoadLists(masterlistPath.string(), "")); + + EXPECT_NO_THROW(db_->WriteUserMetadata(minimalOutputPath_.string(), true)); + + std::string expectedContent = "bash_tags:\n []\nglobals:\n []\nplugins:\n []"; + + EXPECT_EQ(expectedContent, GetFileContent(minimalOutputPath_)); +} + +TEST_P(DatabaseInterfaceTest, writeUserMetadataShouldShouldWriteUserMetadata) { + ASSERT_NO_THROW(GenerateMasterlist()); + ASSERT_NO_THROW(boost::filesystem::copy(masterlistPath, userlistPath_)); + + boost::filesystem::ofstream masterlist(masterlistPath); + masterlist << "bash_tags:\n []\nglobals:\n []\nplugins:\n []"; + masterlist.close(); + + ASSERT_NO_THROW(db_->LoadLists(masterlistPath.string(), userlistPath_.string())); + + EXPECT_NO_THROW(db_->WriteUserMetadata(minimalOutputPath_.string(), true)); + + EXPECT_FALSE(GetFileContent(minimalOutputPath_).empty()); +} + TEST_P(DatabaseInterfaceTest, sortPluginsShouldSucceedIfPassedValidArguments) { std::vector expectedOrder = { masterFile, @@ -260,6 +348,226 @@ TEST_P(DatabaseInterfaceTest, getMasterlistRevisionShouldSucceedIfAnEditedVersio EXPECT_TRUE(info.is_modified); } +TEST_P(DatabaseInterfaceTest, getKnownBashTagsShouldReturnAllBashTagsListedInLoadedMetadata) { + ASSERT_NO_THROW(GenerateMasterlist()); + ASSERT_NO_THROW(GenerateUserlist()); + + ASSERT_NO_THROW(db_->LoadLists(masterlistPath.string(), userlistPath_.string())); + + auto tags = db_->GetKnownBashTags(); + + std::set expectedTags({ + "RaceRelations", + "C.Lighting", + "Actors.ACBS", + "C.Climate", + }); + EXPECT_EQ(expectedTags, tags); +} + +TEST_P(DatabaseInterfaceTest, getGeneralMessagesShouldGetGeneralMessagesFromTheMasterlistAndUserlist) { + ASSERT_NO_THROW(GenerateMasterlist()); + ASSERT_NO_THROW(GenerateUserlist()); + ASSERT_NO_THROW(db_->LoadLists(masterlistPath.string(), userlistPath_.string())); + + auto messages = db_->GetGeneralMessages(); + + std::vector expectedMessages({ + Message(MessageType::say, generalMasterlistMessage), + Message(MessageType::say, generalUserlistMessage), + }); + EXPECT_EQ(expectedMessages, messages); +} + +TEST_P(DatabaseInterfaceTest, getPluginMetadataShouldReturnAnEmptyPluginMetadataObjectIfThePluginHasNoMetadata) { + auto metadata = db_->GetPluginMetadata(blankEsm); + + EXPECT_TRUE(metadata.HasNameOnly()); +} + +TEST_P(DatabaseInterfaceTest, getPluginMetadataShouldReturnMergedMasterAndUserMetadataForTheGivenPlugin) { + ASSERT_NO_THROW(GenerateMasterlist()); + ASSERT_NO_THROW(GenerateUserlist()); + ASSERT_NO_THROW(db_->LoadLists(masterlistPath.string(), userlistPath_.string())); + + auto metadata = db_->GetPluginMetadata(blankEsm); + + std::set expectedLoadAfter({ + File(masterFile), + File(blankDifferentEsm), + }); + EXPECT_EQ(expectedLoadAfter, metadata.LoadAfter()); +} + +TEST_P(DatabaseInterfaceTest, getPluginUserMetadataShouldReturnAnEmptyPluginMetadataObjectIfThePluginHasNoUserMetadata) { + ASSERT_NO_THROW(GenerateMasterlist()); + ASSERT_NO_THROW(GenerateUserlist()); + ASSERT_NO_THROW(db_->LoadLists(masterlistPath.string(), userlistPath_.string())); + + auto metadata = db_->GetPluginUserMetadata(blankDifferentEsm); + + EXPECT_TRUE(metadata.HasNameOnly()); +} + +TEST_P(DatabaseInterfaceTest, getPluginUserMetadataShouldReturnOnlyUserMetadataForTheGivenPlugin) { + ASSERT_NO_THROW(GenerateMasterlist()); + ASSERT_NO_THROW(GenerateUserlist()); + ASSERT_NO_THROW(db_->LoadLists(masterlistPath.string(), userlistPath_.string())); + + auto metadata = db_->GetPluginUserMetadata(blankEsm); + + std::set expectedLoadAfter({ + File(blankDifferentEsm), + }); + EXPECT_EQ(expectedLoadAfter, metadata.LoadAfter()); +} + +TEST_P(DatabaseInterfaceTest, setPluginUserMetadataShouldReplaceExistingUserMetadataWithTheGivenMetadata) { + ASSERT_NO_THROW(GenerateMasterlist()); + ASSERT_NO_THROW(GenerateUserlist()); + ASSERT_NO_THROW(db_->LoadLists(masterlistPath.string(), userlistPath_.string())); + + PluginMetadata newMetadata(blankDifferentEsp); + newMetadata.Reqs(std::set({File(masterFile)})); + + db_->SetPluginUserMetadata(newMetadata); + + auto metadata = db_->GetPluginUserMetadata(blankDifferentEsp); + + std::set expectedLoadAfter({ + File(blankDifferentEsm), + }); + EXPECT_TRUE(metadata.Incs().empty()); + EXPECT_EQ(newMetadata.Reqs(), metadata.Reqs()); +} + +TEST_P(DatabaseInterfaceTest, setPluginUserMetadataShouldNotAffectExistingMasterlistMetadata) { + ASSERT_NO_THROW(GenerateMasterlist()); + ASSERT_NO_THROW(GenerateUserlist()); + ASSERT_NO_THROW(db_->LoadLists(masterlistPath.string(), userlistPath_.string())); + + PluginMetadata newMetadata(blankEsm); + newMetadata.Reqs(std::set({File(masterFile)})); + + db_->SetPluginUserMetadata(newMetadata); + + auto metadata = db_->GetPluginMetadata(blankEsm); + + std::set expectedLoadAfter({ + File(masterFile), + }); + EXPECT_EQ(expectedLoadAfter, metadata.LoadAfter()); +} + +TEST_P(DatabaseInterfaceTest, discardPluginUserMetadataShouldDiscardAllUserMetadataForTheGivenPlugin) { + ASSERT_NO_THROW(GenerateMasterlist()); + ASSERT_NO_THROW(GenerateUserlist()); + ASSERT_NO_THROW(db_->LoadLists(masterlistPath.string(), userlistPath_.string())); + + db_->DiscardPluginUserMetadata(blankEsm); + + auto metadata = db_->GetPluginUserMetadata(blankEsm); + EXPECT_TRUE(metadata.HasNameOnly()); + +} + +TEST_P(DatabaseInterfaceTest, discardPluginUserMetadataShouldNotDiscardMasterlistMetadataForTheGivenPlugin) { + ASSERT_NO_THROW(GenerateMasterlist()); + ASSERT_NO_THROW(GenerateUserlist()); + ASSERT_NO_THROW(db_->LoadLists(masterlistPath.string(), userlistPath_.string())); + + db_->DiscardPluginUserMetadata(blankEsm); + + auto metadata = db_->GetPluginMetadata(blankEsm); + + std::set expectedLoadAfter({ + File(masterFile), + }); + EXPECT_EQ(expectedLoadAfter, metadata.LoadAfter()); +} + +TEST_P(DatabaseInterfaceTest, discardPluginUserMetadataShouldNotDiscardUserMetadataForOtherPlugins) { + ASSERT_NO_THROW(GenerateMasterlist()); + ASSERT_NO_THROW(GenerateUserlist()); + ASSERT_NO_THROW(db_->LoadLists(masterlistPath.string(), userlistPath_.string())); + + db_->DiscardPluginUserMetadata(blankEsm); + + auto metadata = db_->GetPluginUserMetadata(blankDifferentEsp); + + EXPECT_FALSE(metadata.HasNameOnly()); +} + +TEST_P(DatabaseInterfaceTest, discardPluginUserMetadataShouldNotDiscardGeneralMessages) { + ASSERT_NO_THROW(GenerateMasterlist()); + ASSERT_NO_THROW(GenerateUserlist()); + ASSERT_NO_THROW(db_->LoadLists(masterlistPath.string(), userlistPath_.string())); + + db_->DiscardPluginUserMetadata(blankEsm); + + auto messages = db_->GetGeneralMessages(); + + std::vector expectedMessages({ + Message(MessageType::say, generalMasterlistMessage), + Message(MessageType::say, generalUserlistMessage), + }); + EXPECT_EQ(expectedMessages, messages); +} + +TEST_P(DatabaseInterfaceTest, discardPluginUserMetadataShouldNotDiscardKnownBashTags) { + ASSERT_NO_THROW(GenerateMasterlist()); + ASSERT_NO_THROW(GenerateUserlist()); + ASSERT_NO_THROW(db_->LoadLists(masterlistPath.string(), userlistPath_.string())); + + db_->DiscardPluginUserMetadata(blankEsm); + + auto tags = db_->GetKnownBashTags(); + + std::set expectedTags({ + "RaceRelations", + "C.Lighting", + "Actors.ACBS", + "C.Climate", + }); + EXPECT_EQ(expectedTags, tags); +} + +TEST_P(DatabaseInterfaceTest, discardAllUserMetadataShouldDiscardAllUserMetadataAndNoMasterlistMetadata) { + ASSERT_NO_THROW(GenerateMasterlist()); + ASSERT_NO_THROW(GenerateUserlist()); + ASSERT_NO_THROW(db_->LoadLists(masterlistPath.string(), userlistPath_.string())); + + db_->DiscardAllUserMetadata(); + + auto metadata = db_->GetPluginUserMetadata(blankEsm); + EXPECT_TRUE(metadata.HasNameOnly()); + + metadata = db_->GetPluginUserMetadata(blankDifferentEsp); + EXPECT_TRUE(metadata.HasNameOnly()); + + metadata = db_->GetPluginMetadata(blankEsm); + + std::set expectedLoadAfter({ + File(masterFile), + }); + EXPECT_EQ(expectedLoadAfter, metadata.LoadAfter()); + + auto messages = db_->GetGeneralMessages(); + + std::vector expectedMessages({ + Message(MessageType::say, generalMasterlistMessage), + }); + EXPECT_EQ(expectedMessages, messages); + + auto tags = db_->GetKnownBashTags(); + + std::set expectedTags({ + "Actors.ACBS", + "C.Climate", + }); + EXPECT_EQ(expectedTags, tags); +} + TEST_P(DatabaseInterfaceTest, getPluginTagsShouldReturnOkAndOutputEmptyNonModifiedArraysIfAPluginWithoutTagsIsQueried) { ASSERT_NO_THROW(GenerateMasterlist()); ASSERT_NO_THROW(db_->LoadLists(masterlistPath.string(), "")); @@ -454,11 +762,7 @@ TEST_P(DatabaseInterfaceTest, writeMinimalListShouldWriteOnlyBashTagsAndDirtyInf EXPECT_NO_THROW(db_->WriteMinimalList(minimalOutputPath_.string(), true)); - boost::filesystem::ifstream in(minimalOutputPath_); - std::stringstream content; - content << in.rdbuf(); - - EXPECT_EQ(GetExpectedMinimalContent(), content.str()); + EXPECT_EQ(GetExpectedMinimalContent(), GetFileContent(minimalOutputPath_)); } } }