amplify-swift/AmplifyTests/CategoryTests/Predictions/PredictionsCategoryConfigur...

433 lines
15 KiB
Swift

//
// Copyright Amazon.com Inc. or its affiliates.
// All Rights Reserved.
//
// SPDX-License-Identifier: Apache-2.0
//
import XCTest
@testable import Amplify
@testable import AmplifyTestCommon
class PredictionsCategoryConfigurationTests: XCTestCase {
override func setUp() async throws {
await Amplify.reset()
}
/// Test if we can add a new prediction plugin
///
/// - Given: UnConfigured Amplify framework
/// - When:
/// - I add a new Prediction plugin to Amplify
/// - Then:
/// - Plugin should be added without throwing any error
///
func testCanAddPlugin() throws {
let plugin = MockPredictionsCategoryPlugin()
XCTAssertNoThrow(try Amplify.add(plugin: plugin))
}
/// Test if Prediction plugin can be configured
///
/// - Given: UnConfigured Amplify framework
/// - When:
/// - I add a new Prediction plugin and add configuration for the plugin
/// - Then:
/// - Prediction plugin should be configured correctly
///
func testCanConfigurePlugin() throws {
let plugin = MockPredictionsCategoryPlugin()
try Amplify.add(plugin: plugin)
let config = PredictionsCategoryConfiguration(
plugins: ["MockPredictionsCategoryPlugin": true]
)
let amplifyConfig = AmplifyConfiguration(predictions: config)
try Amplify.configure(amplifyConfig)
XCTAssertNotNil(Amplify.Predictions)
XCTAssertNotNil(try Amplify.Predictions.getPlugin(for: "MockPredictionsCategoryPlugin"))
}
/// Test if resetting Prediction category works
///
/// - Given: Amplify framework configured with Prediction plugin
/// - When:
/// - I call await Amplify.reset()
/// - Then:
/// - The plugin should invoke the reset method.
///
func testCanResetPlugin() async throws {
let plugin = MockPredictionsCategoryPlugin()
let resetWasInvoked = expectation(description: "reset() was invoked")
plugin.listeners.append { message in
if message == "reset" {
resetWasInvoked.fulfill()
}
}
try Amplify.add(plugin: plugin)
let config = PredictionsCategoryConfiguration(
plugins: ["MockPredictionsCategoryPlugin": true]
)
let amplifyConfig = AmplifyConfiguration(predictions: config)
try Amplify.configure(amplifyConfig)
await Amplify.reset()
await waitForExpectations(timeout: 1.0)
}
/// Test whether calling reset removes the plugin added
///
/// - Given: Amplify framework configured with Prediction plugin
/// - When:
/// - I call Amplify.reset
/// - Then:
/// - Predicitons plugin should no longer work
///
func testResetRemovesAddedPlugin() async throws {
let plugin = MockPredictionsCategoryPlugin()
try Amplify.add(plugin: plugin)
let config = PredictionsCategoryConfiguration(
plugins: ["MockPredictionsCategoryPlugin": true]
)
let amplifyConfig = AmplifyConfiguration(predictions: config)
try Amplify.configure(amplifyConfig)
await Amplify.reset()
XCTAssertThrowsError(try Amplify.Predictions.getPlugin(for: "MockPredictionsCategoryPlugin"),
"Getting a plugin after reset() should throw") { error in
guard case PredictionsError.configuration = error else {
XCTFail("Expected PluginError.noSuchPlugin")
return
}
}
}
/// Test if we can register multiple plugins
///
/// - Given: UnConfigured Amplify framework
/// - When:
/// - I configure Amplify with multiple plugins for Predictions
/// - Then:
/// - I should be able to access individual plugins I added.
///
func testCanRegisterMultiplePlugins() throws {
let plugin1 = MockPredictionsCategoryPlugin()
try Amplify.add(plugin: plugin1)
let plugin2 = MockSecondPredictionsCategoryPlugin()
try Amplify.add(plugin: plugin2)
let config = PredictionsCategoryConfiguration(
plugins: [
"MockPredictionsCategoryPlugin": true,
"MockSecondPredictionsCategoryPlugin": true
]
)
let amplifyConfig = AmplifyConfiguration(predictions: config)
try Amplify.configure(amplifyConfig)
XCTAssertNotNil(try Amplify.Predictions.getPlugin(for: "MockPredictionsCategoryPlugin"))
XCTAssertNotNil(try Amplify.Predictions.getPlugin(for: "MockSecondPredictionsCategoryPlugin"))
}
/// Test if the default plugin works
///
/// - Given: Amplify configured with Prediction plugin
/// - When:
/// - I invoke a API from prediction with default invocation
/// - Then:
/// - API should complete without error
///
func testCanUseDefaultPluginIfOnlyOnePlugin() throws {
let plugin = MockPredictionsCategoryPlugin()
let methodInvokedOnDefaultPlugin = expectation(description: "test method invoked on default plugin")
plugin.listeners.append { message in
if message == "textToTranslate" {
methodInvokedOnDefaultPlugin.fulfill()
}
}
try Amplify.add(plugin: plugin)
let config = PredictionsCategoryConfiguration(plugins: ["MockPredictionsCategoryPlugin": true])
let amplifyConfig = AmplifyConfiguration(predictions: config)
try Amplify.configure(amplifyConfig)
_ = Amplify.Predictions.convert(textToTranslate: "Sample",
language: nil,
targetLanguage: nil,
options: nil,
listener: nil)
waitForExpectations(timeout: 1.0)
}
/// Test if I can pick a specific plugin
///
/// - Given: Amplify configured with multiple Prediction plugins
/// - When:
/// - I coose one plugin and call one of the Prediction API
/// - Then:
/// - API should complete without error for one plugin
///
func testCanUseSpecifiedPlugin() throws {
let plugin1 = MockPredictionsCategoryPlugin()
let methodShouldNotBeInvokedOnDefaultPlugin =
expectation(description: "test method should not be invoked on default plugin")
methodShouldNotBeInvokedOnDefaultPlugin.isInverted = true
plugin1.listeners.append { message in
if message == "textToTranslate" {
methodShouldNotBeInvokedOnDefaultPlugin.fulfill()
}
}
try Amplify.add(plugin: plugin1)
let plugin2 = MockSecondPredictionsCategoryPlugin()
let methodShouldBeInvokedOnSecondPlugin =
expectation(description: "test method should be invoked on second plugin")
plugin2.listeners.append { message in
if message == "textToTranslate" {
methodShouldBeInvokedOnSecondPlugin.fulfill()
}
}
try Amplify.add(plugin: plugin2)
let config = PredictionsCategoryConfiguration(
plugins: [
"MockPredictionsCategoryPlugin": true,
"MockSecondPredictionsCategoryPlugin": true
]
)
let amplifyConfig = AmplifyConfiguration(predictions: config)
try Amplify.configure(amplifyConfig)
_ = try Amplify.Predictions.getPlugin(for: "MockSecondPredictionsCategoryPlugin")
.convert(textToTranslate: "Sample",
language: nil,
targetLanguage: nil,
options: nil,
listener: nil)
waitForExpectations(timeout: 1.0)
}
/// Test if we get error when trying default plugin when multiple plugin added.
///
/// - Given: Amplify configured with multiple prediction plugin
/// - When:
/// - I try to invoke an API with default plugin
/// - Then:
/// - Should throw an exception
///
func testPreconditionFailureInvokingWithMultiplePlugins() throws {
let plugin1 = MockPredictionsCategoryPlugin()
try Amplify.add(plugin: plugin1)
let plugin2 = MockSecondPredictionsCategoryPlugin()
try Amplify.add(plugin: plugin2)
let config = PredictionsCategoryConfiguration(
plugins: [
"MockPredictionsCategoryPlugin": true,
"MockSecondPredictionsCategoryPlugin": true
]
)
let amplifyConfig = AmplifyConfiguration(predictions: config)
try Amplify.configure(amplifyConfig)
try XCTAssertThrowFatalError {
_ = Amplify.Predictions.convert(textToTranslate: "Sample",
language: nil,
targetLanguage: nil,
options: nil,
listener: nil)
}
}
/// Test if configuration Prediction plugin directly works
///
/// - Given: Amplify with Prediction plugin configured
/// - When:
/// - I try to add a new configuration to the same plugin
/// - Then:
/// - Should work without any error.
///
func testCanConfigurePluginDirectly() throws {
let plugin = MockPredictionsCategoryPlugin()
let configureShouldBeInvokedFromCategory =
expectation(description: "Configure should be invoked by Amplify.configure()")
let configureShouldBeInvokedDirectly =
expectation(description: "Configure should be invoked by getPlugin().configure()")
var invocationCount = 0
plugin.listeners.append { message in
if message == "configure(using:)" {
invocationCount += 1
switch invocationCount {
case 1: configureShouldBeInvokedFromCategory.fulfill()
case 2: configureShouldBeInvokedDirectly.fulfill()
default: XCTFail("Expected configure() to be called only two times, but got \(invocationCount)")
}
}
}
try Amplify.add(plugin: plugin)
let config = PredictionsCategoryConfiguration(
plugins: ["MockPredictionsCategoryPlugin": true]
)
let amplifyConfig = AmplifyConfiguration(predictions: config)
try Amplify.configure(amplifyConfig)
try Amplify.Predictions.getPlugin(for: "MockPredictionsCategoryPlugin").configure(using: true)
waitForExpectations(timeout: 1.0)
}
/// Test if unconfigured plugin throws an error
///
/// - Given: An unconfigured Amplify framework with Prediction plugin added
/// - When:
/// - Invoke an API in prediction
/// - Then:
/// - I should get an exception
///
func testPreconditionFailureInvokingBeforeConfig() throws {
let plugin = MockPredictionsCategoryPlugin()
try Amplify.add(plugin: plugin)
// Remember, this test must be invoked with a category that doesn't include an Amplify-supplied default plugin
try XCTAssertThrowFatalError {
_ = Amplify.Predictions.convert(textToTranslate: "Sample",
language: nil,
targetLanguage: nil,
options: nil,
listener: nil)
}
}
// MARK: - Test internal config behavior guarantees
/// Test if configuring twice throws an exception
///
/// - Given: Amplify with Prediction plugin configured
/// - When:
/// - I try to configure Prediction again
/// - Then:
/// - Should throw an exception
///
func testThrowsConfiguringTwice() throws {
let plugin = MockPredictionsCategoryPlugin()
try Amplify.add(plugin: plugin)
let config = PredictionsCategoryConfiguration(
plugins: ["MockPredictionsCategoryPlugin": true]
)
try Amplify.Predictions.configure(using: config)
XCTAssertThrowsError(try Amplify.Predictions.configure(using: config),
"configure() an already configured plugin should throw") { error in
guard case ConfigurationError.amplifyAlreadyConfigured = error else {
XCTFail("Expected ConfigurationError.amplifyAlreadyConfigured")
return
}
}
}
/// Test if configuring after reset works
///
/// - Given: Amplify framework with Predictons configured
/// - When:
/// - I reset Amplify and then configure again
/// - Then:
/// - Should not throw any error
///
func testCanConfigureAfterReset() async throws {
let plugin = MockPredictionsCategoryPlugin()
try Amplify.add(plugin: plugin)
let config = PredictionsCategoryConfiguration(
plugins: ["MockPredictionsCategoryPlugin": true]
)
try Amplify.Predictions.configure(using: config)
await Amplify.Predictions.reset()
XCTAssertNoThrow(try Amplify.Predictions.configure(using: config))
}
/// Test that Amplify logs a warning if it encounters a plugin configuration key without a corresponding plugin
///
/// - Given:
/// - A configuration with a nonexistent plugin key specified
/// - When:
/// - I invoke `Amplify.configure()`
/// - Then:
/// - I should see a log warning
///
func testWarnsOnMissingPlugin() throws {
let warningReceived = expectation(description: "Warning message received")
let loggingPlugin = MockLoggingCategoryPlugin()
loggingPlugin.listeners.append { message in
if message.starts(with: "warn(_:): No plugin found") {
warningReceived.fulfill()
}
}
let loggingConfig = LoggingCategoryConfiguration(
plugins: [loggingPlugin.key: true]
)
try Amplify.add(plugin: loggingPlugin)
let categoryConfig = PredictionsCategoryConfiguration(
plugins: ["NonExistentPlugin": true]
)
let amplifyConfig = AmplifyConfiguration(logging: loggingConfig, predictions: categoryConfig)
try Amplify.configure(amplifyConfig)
waitForExpectations(timeout: 0.1)
}
/// Test if adding a plugin after configuration throws an error
///
/// - Given: Amplify is configured
/// - When:
/// - Add is called for Predictions category
/// - Then:
/// - Should throw an exception
///
func testAddAfterConfigureThrowsError() throws {
let plugin = MockPredictionsCategoryPlugin()
try Amplify.add(plugin: plugin)
let config = PredictionsCategoryConfiguration(
plugins: ["MockPredictionsCategoryPlugin": true]
)
let amplifyConfig = AmplifyConfiguration(predictions: config)
try Amplify.configure(amplifyConfig)
XCTAssertThrowsError(try Amplify.add(plugin: plugin),
"configure() an already configured plugin should throw") { error in
guard case ConfigurationError.amplifyAlreadyConfigured = error else {
XCTFail("Expected ConfigurationError.amplifyAlreadyConfigured")
return
}
}
}
}