From 3d52a6a1e03a0a615079a3d58b5002da93ef4bf0 Mon Sep 17 00:00:00 2001
From: Thomas Williamson
Date: Thu, 29 Feb 2024 09:26:01 +0100
Subject: [PATCH 01/43] Move to BCApps
---
.../App/File System/README.md | 6 +
.../App/File System/app.json | 40 +
.../FileSystemAdmin.PermissionSet.al | 23 +
.../FileSystemEdit.PermissionSet.al | 24 +
.../FileSystemObjects.PermissionSetExt.al | 34 +
.../FileSystemRead.PermissionSet.al | 20 +
.../src/Account/FileAccount.Codeunit.al | 46 +
.../src/Account/FileAccount.Table.al | 68 +
.../src/Account/FileAccountImpl.Codeunit.al | 247 +++
.../src/Account/FileAccountWizard.Page.al | 528 ++++++
.../src/Account/FileAccounts.Page.al | 332 ++++
.../src/Connector/FileSystemConnector.Enum.al | 14 +
.../FileSystemConnector.Interface.al | 148 ++
.../Connector/FileSystemConnector.Table.al | 39 +
.../FileSystemConnectorLogo.Table.al | 35 +
.../src/FileSystem/FileSystem.Codeunit.al | 258 +++
.../src/FileSystem/FileSystemImp.Codeunit.al | 208 +++
.../src/Lookup/FileAccountBrowser.Page.al | 315 ++++
.../src/Lookup/FileAccountContent.Table.al | 39 +
.../src/Lookup/FilePaginationData.Codeunit.al | 33 +
.../File System/src/Lookup/FileType.Enum.al | 31 +
.../src/Lookup/FolderNameInput.Page.al | 33 +
.../src/Scenario/FileAccountScenario.Table.al | 74 +
.../src/Scenario/FileScenario.Codeunit.al | 76 +
.../src/Scenario/FileScenario.Enum.al | 24 +
.../src/Scenario/FileScenario.Table.al | 42 +
.../src/Scenario/FileScenarioImpl.Codeunit.al | 329 ++++
.../src/Scenario/FileScenarioSetup.Page.al | 198 +++
.../src/Scenario/FileScenariosFactBox.Page.al | 40 +
.../Scenario/FileScenariosForAccount.Page.al | 65 +
.../FileSystemAdmin.PermissionSet.al | 19 +
.../FileSystemEdit.PermissionSet.al | 21 +
.../Test Library/File System/app.json | 39 +
.../File System/src/ConnectorMock.Codeunit.al | 136 ++
.../src/FileScenarioMock.Codeunit.al | 32 +
.../File System/src/TestFileAccount.Table.al | 33 +
.../src/TestFileConnectorSetup.Table.al | 44 +
.../src/TestFileScenario.EnumExt.al | 15 +
.../src/TestFileSystemConnector.Codeunit.al | 136 ++
.../src/TestFileSystemConnector.EnumExt.al | 16 +
.../Test/File System/app.json | 105 ++
.../src/FileAccountsTest.Codeunit.al | 638 +++++++
.../src/FileScenarioPageTest.Codeunit.al | 208 +++
.../src/FileScenarioTest.Codeunit.al | 285 +++
.../src/FileSystemlTest.Codeunit.al | 1552 +++++++++++++++++
.../FileAccountsSelectionMock.Codeunit.al | 45 +
46 files changed, 6693 insertions(+)
create mode 100644 src/System Application/App/File System/README.md
create mode 100644 src/System Application/App/File System/app.json
create mode 100644 src/System Application/App/File System/permissions/FileSystemAdmin.PermissionSet.al
create mode 100644 src/System Application/App/File System/permissions/FileSystemEdit.PermissionSet.al
create mode 100644 src/System Application/App/File System/permissions/FileSystemObjects.PermissionSetExt.al
create mode 100644 src/System Application/App/File System/permissions/FileSystemRead.PermissionSet.al
create mode 100644 src/System Application/App/File System/src/Account/FileAccount.Codeunit.al
create mode 100644 src/System Application/App/File System/src/Account/FileAccount.Table.al
create mode 100644 src/System Application/App/File System/src/Account/FileAccountImpl.Codeunit.al
create mode 100644 src/System Application/App/File System/src/Account/FileAccountWizard.Page.al
create mode 100644 src/System Application/App/File System/src/Account/FileAccounts.Page.al
create mode 100644 src/System Application/App/File System/src/Connector/FileSystemConnector.Enum.al
create mode 100644 src/System Application/App/File System/src/Connector/FileSystemConnector.Interface.al
create mode 100644 src/System Application/App/File System/src/Connector/FileSystemConnector.Table.al
create mode 100644 src/System Application/App/File System/src/Connector/FileSystemConnectorLogo.Table.al
create mode 100644 src/System Application/App/File System/src/FileSystem/FileSystem.Codeunit.al
create mode 100644 src/System Application/App/File System/src/FileSystem/FileSystemImp.Codeunit.al
create mode 100644 src/System Application/App/File System/src/Lookup/FileAccountBrowser.Page.al
create mode 100644 src/System Application/App/File System/src/Lookup/FileAccountContent.Table.al
create mode 100644 src/System Application/App/File System/src/Lookup/FilePaginationData.Codeunit.al
create mode 100644 src/System Application/App/File System/src/Lookup/FileType.Enum.al
create mode 100644 src/System Application/App/File System/src/Lookup/FolderNameInput.Page.al
create mode 100644 src/System Application/App/File System/src/Scenario/FileAccountScenario.Table.al
create mode 100644 src/System Application/App/File System/src/Scenario/FileScenario.Codeunit.al
create mode 100644 src/System Application/App/File System/src/Scenario/FileScenario.Enum.al
create mode 100644 src/System Application/App/File System/src/Scenario/FileScenario.Table.al
create mode 100644 src/System Application/App/File System/src/Scenario/FileScenarioImpl.Codeunit.al
create mode 100644 src/System Application/App/File System/src/Scenario/FileScenarioSetup.Page.al
create mode 100644 src/System Application/App/File System/src/Scenario/FileScenariosFactBox.Page.al
create mode 100644 src/System Application/App/File System/src/Scenario/FileScenariosForAccount.Page.al
create mode 100644 src/System Application/Test Library/File System/Permissions/FileSystemAdmin.PermissionSet.al
create mode 100644 src/System Application/Test Library/File System/Permissions/FileSystemEdit.PermissionSet.al
create mode 100644 src/System Application/Test Library/File System/app.json
create mode 100644 src/System Application/Test Library/File System/src/ConnectorMock.Codeunit.al
create mode 100644 src/System Application/Test Library/File System/src/FileScenarioMock.Codeunit.al
create mode 100644 src/System Application/Test Library/File System/src/TestFileAccount.Table.al
create mode 100644 src/System Application/Test Library/File System/src/TestFileConnectorSetup.Table.al
create mode 100644 src/System Application/Test Library/File System/src/TestFileScenario.EnumExt.al
create mode 100644 src/System Application/Test Library/File System/src/TestFileSystemConnector.Codeunit.al
create mode 100644 src/System Application/Test Library/File System/src/TestFileSystemConnector.EnumExt.al
create mode 100644 src/System Application/Test/File System/app.json
create mode 100644 src/System Application/Test/File System/src/FileAccountsTest.Codeunit.al
create mode 100644 src/System Application/Test/File System/src/FileScenarioPageTest.Codeunit.al
create mode 100644 src/System Application/Test/File System/src/FileScenarioTest.Codeunit.al
create mode 100644 src/System Application/Test/File System/src/FileSystemlTest.Codeunit.al
create mode 100644 src/System Application/Test/File System/src/Mocks/FileAccountsSelectionMock.Codeunit.al
diff --git a/src/System Application/App/File System/README.md b/src/System Application/App/File System/README.md
new file mode 100644
index 0000000000..aa74a80495
--- /dev/null
+++ b/src/System Application/App/File System/README.md
@@ -0,0 +1,6 @@
+Provides an API that lets you connect file system accounts to Business Central so that people can access files outside BC. The file system module consists of the following main entities:
+
+### File Account
+An file account holds the information needed to access a file system from Business Central.
+
+...
\ No newline at end of file
diff --git a/src/System Application/App/File System/app.json b/src/System Application/App/File System/app.json
new file mode 100644
index 0000000000..e9b596cfbc
--- /dev/null
+++ b/src/System Application/App/File System/app.json
@@ -0,0 +1,40 @@
+{
+ "id": "c9c54414-80c3-4cc9-98c6-589158882774",
+ "name": "File System",
+ "publisher": "Microsoft",
+ "brief": "Enables user to send emails from Business Central.",
+ "description": "Enables user to send emails from Business Central.",
+ "version": "25.0.0.0",
+ "privacyStatement": "https://go.microsoft.com/fwlink/?linkid=724009",
+ "EULA": "https://go.microsoft.com/fwlink/?linkid=2009120",
+ "help": "https://go.microsoft.com/fwlink/?linkid=2103698",
+ "url": "https://go.microsoft.com/fwlink/?linkid=724011",
+ "logo": "",
+ "dependencies": [
+ ],
+ "internalsVisibleTo": [
+ {
+ "id": "fff6eee5-083f-4f07-9a49-e34f7e2aad77",
+ "name": "File Systen Test",
+ "publisher": "Microsoft"
+ },
+ {
+ "id": "f188754b-3ffb-443a-9507-f5fbdae3af2c",
+ "name": "File System Test Library",
+ "publisher": "Microsoft"
+ }
+ ],
+ "screenshots": [
+
+ ],
+ "platform": "25.0.0.0",
+ "application": "25.0.0.0",
+ "idRanges": [
+ {
+ "from": 70000,
+ "to": 70199
+ }
+ ],
+ "target": "OnPrem",
+ "contextSensitiveHelpUrl": "https://go.microsoft.com/fwlink/?linkid=2134520"
+}
\ No newline at end of file
diff --git a/src/System Application/App/File System/permissions/FileSystemAdmin.PermissionSet.al b/src/System Application/App/File System/permissions/FileSystemAdmin.PermissionSet.al
new file mode 100644
index 0000000000..45aaffabee
--- /dev/null
+++ b/src/System Application/App/File System/permissions/FileSystemAdmin.PermissionSet.al
@@ -0,0 +1,23 @@
+// ------------------------------------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License. See License.txt in the project root for license information.
+// ------------------------------------------------------------------------------------------------
+
+namespace System.FileSystem;
+
+permissionset 70000 "File System - Admin"
+{
+ Access = Public;
+ Assignable = true;
+ Caption = 'File System - Admin';
+
+ IncludedPermissionSets = "File System - Edit";
+
+ Permissions =
+ tabledata "File Account" = RMID,
+ tabledata "File System Connector" = RMID,
+ tabledata "File System Connector Logo" = RMID,
+ tabledata "File Account Scenario" = RMID,
+ tabledata "File Scenario" = RMID,
+ tabledata "File Account Content" = RMID;
+}
diff --git a/src/System Application/App/File System/permissions/FileSystemEdit.PermissionSet.al b/src/System Application/App/File System/permissions/FileSystemEdit.PermissionSet.al
new file mode 100644
index 0000000000..e4314d462b
--- /dev/null
+++ b/src/System Application/App/File System/permissions/FileSystemEdit.PermissionSet.al
@@ -0,0 +1,24 @@
+// ------------------------------------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License. See License.txt in the project root for license information.
+// ------------------------------------------------------------------------------------------------
+
+namespace System.FileSystem;
+
+using System.Environment;
+
+permissionset 70002 "File System - Read"
+{
+ Access = Internal;
+ Assignable = false;
+
+ IncludedPermissionSets = "File System - Objects";
+
+ Permissions = tabledata "File Account" = r,
+ tabledata "File System Connector" = r,
+ tabledata "File System Connector Logo" = r,
+ tabledata "File Account Scenario" = r,
+ tabledata "File Scenario" = r,
+ tabledata "File Account Content" = r,
+ tabledata Media = r; // File System Account Wizard requires this
+}
\ No newline at end of file
diff --git a/src/System Application/App/File System/permissions/FileSystemObjects.PermissionSetExt.al b/src/System Application/App/File System/permissions/FileSystemObjects.PermissionSetExt.al
new file mode 100644
index 0000000000..de04bf3b01
--- /dev/null
+++ b/src/System Application/App/File System/permissions/FileSystemObjects.PermissionSetExt.al
@@ -0,0 +1,34 @@
+// ------------------------------------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License. See License.txt in the project root for license information.
+// ------------------------------------------------------------------------------------------------
+
+namespace System.FileSystem;
+
+permissionset 70001 "File System - Objects"
+{
+ Access = Internal;
+ Assignable = false;
+
+ Permissions =
+ table "File Account" = X,
+ table "File System Connector" = X,
+ table "File System Connector Logo" = X,
+ table "File Account Scenario" = X,
+ table "File Scenario" = X,
+ table "File Account Content" = X,
+ codeunit "File Account" = X,
+ codeunit "File Account Impl." = X,
+ codeunit "File Scenario" = X,
+ codeunit "File Pagination Data" = X,
+ codeunit "File System Impl." = X,
+ codeunit "File System" = X,
+ codeunit "File Scenario Impl." = X,
+ page "File Accounts" = X,
+ page "File Account Wizard" = X,
+ page "Folder Name Input" = X,
+ page "File Scenarios FactBox" = X,
+ page "File Scenarios for Account" = X,
+ page "File Scenario Setup" = X,
+ page "File Account Browser" = X;
+}
diff --git a/src/System Application/App/File System/permissions/FileSystemRead.PermissionSet.al b/src/System Application/App/File System/permissions/FileSystemRead.PermissionSet.al
new file mode 100644
index 0000000000..43fb9e2e0d
--- /dev/null
+++ b/src/System Application/App/File System/permissions/FileSystemRead.PermissionSet.al
@@ -0,0 +1,20 @@
+// ------------------------------------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License. See License.txt in the project root for license information.
+// ------------------------------------------------------------------------------------------------
+
+namespace System.FileSystem;
+
+using System.Environment;
+
+permissionset 70003 "File System - Edit"
+{
+ Access = Public;
+ Assignable = false;
+ Caption = 'File System - Edit';
+
+ IncludedPermissionSets = "File System - Read";
+
+ Permissions = tabledata "File System Connector Logo" = imd,
+ tabledata "Tenant Media" = imd;
+}
\ No newline at end of file
diff --git a/src/System Application/App/File System/src/Account/FileAccount.Codeunit.al b/src/System Application/App/File System/src/Account/FileAccount.Codeunit.al
new file mode 100644
index 0000000000..d16f624814
--- /dev/null
+++ b/src/System Application/App/File System/src/Account/FileAccount.Codeunit.al
@@ -0,0 +1,46 @@
+// ------------------------------------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License. See License.txt in the project root for license information.
+// ------------------------------------------------------------------------------------------------
+
+namespace System.FileSystem;
+
+///
+/// Provides functionality to work with file accounts.
+///
+
+codeunit 70000 "File Account"
+{
+ Access = Public;
+
+ ///
+ /// Gets all of the file accounts registered in Business Central.
+ ///
+ /// Flag, used to determine whether to load the logos for the accounts.
+ /// Out parameter holding the file accounts.
+ procedure GetAllAccounts(LoadLogos: Boolean; var TempFileAccount: Record "File Account" temporary)
+ begin
+ FileAccountImpl.GetAllAccounts(LoadLogos, TempFileAccount);
+ end;
+
+ ///
+ /// Gets all of the file accounts registered in Business Central.
+ ///
+ /// Out parameter holding the file accounts.
+ procedure GetAllAccounts(var TempFileAccount: Record "File Account" temporary)
+ begin
+ FileAccountImpl.GetAllAccounts(false, TempFileAccount);
+ end;
+
+ ///
+ /// Checks if there is at least one file account registered in Business Central.
+ ///
+ /// True if there is any account registered in the system, otherwise - false.
+ procedure IsAnyAccountRegistered(): Boolean
+ begin
+ exit(FileAccountImpl.IsAnyAccountRegistered());
+ end;
+
+ var
+ FileAccountImpl: Codeunit "File Account Impl.";
+}
\ No newline at end of file
diff --git a/src/System Application/App/File System/src/Account/FileAccount.Table.al b/src/System Application/App/File System/src/Account/FileAccount.Table.al
new file mode 100644
index 0000000000..e4317b2d2b
--- /dev/null
+++ b/src/System Application/App/File System/src/Account/FileAccount.Table.al
@@ -0,0 +1,68 @@
+// ------------------------------------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License. See License.txt in the project root for license information.
+// ------------------------------------------------------------------------------------------------
+
+namespace System.FileSystem;
+
+///
+/// A common representation of an file account.
+///
+table 70000 "File Account"
+{
+ Extensible = false;
+ TableType = Temporary;
+
+ fields
+ {
+ field(1; "Account Id"; Guid)
+ {
+ DataClassification = SystemMetadata;
+ }
+
+ field(2; Name; Text[250])
+ {
+ DataClassification = SystemMetadata; // Field only in Memory
+ }
+
+ field(4; Connector; Enum "File System Connector")
+ {
+ DataClassification = SystemMetadata;
+ }
+
+ field(5; Logo; Media)
+ {
+ Access = Internal;
+ DataClassification = SystemMetadata;
+ }
+
+ field(6; LogoBlob; Blob)
+ {
+ Access = Internal;
+ DataClassification = SystemMetadata;
+ Subtype = Bitmap;
+ }
+ }
+
+ keys
+ {
+ key(PK; "Account Id", Connector)
+ {
+ Clustered = true;
+ }
+
+ key(Name; Name)
+ {
+ Description = 'Used for sorting';
+ }
+ }
+
+ fieldgroups
+ {
+ fieldgroup(Brick; Logo, Name)
+ {
+
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/src/System Application/App/File System/src/Account/FileAccountImpl.Codeunit.al b/src/System Application/App/File System/src/Account/FileAccountImpl.Codeunit.al
new file mode 100644
index 0000000000..2535a7b38a
--- /dev/null
+++ b/src/System Application/App/File System/src/Account/FileAccountImpl.Codeunit.al
@@ -0,0 +1,247 @@
+// ------------------------------------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License. See License.txt in the project root for license information.
+// ------------------------------------------------------------------------------------------------
+
+namespace System.FileSystem;
+
+using System.Utilities;
+using System.Text;
+
+codeunit 70001 "File Account Impl."
+{
+ Access = Internal;
+ InherentPermissions = X;
+ InherentEntitlements = X;
+ Permissions = tabledata "File System Connector Logo" = rimd,
+ tabledata "File Scenario" = imd;
+
+ procedure GetAllAccounts(LoadLogos: Boolean; var TempFileAccount: Record "File Account" temporary)
+ var
+ FileAccounts: Record "File Account";
+ IFileConnector: Interface "File System Connector";
+ Connector: Enum "File System Connector";
+ begin
+ TempFileAccount.Reset();
+ TempFileAccount.DeleteAll();
+
+ foreach Connector in Connector.Ordinals do begin
+ IFileConnector := Connector;
+
+ FileAccounts.DeleteAll();
+ IFileConnector.GetAccounts(FileAccounts);
+
+ if FileAccounts.FindSet() then
+ repeat
+ TempFileAccount := FileAccounts;
+ TempFileAccount.Connector := Connector;
+
+ if LoadLogos then begin
+ ImportLogo(TempFileAccount, Connector);
+ ImportLogoBlob(TempFileAccount, Connector);
+ end;
+
+ if not TempFileAccount.Insert() then;
+ until FileAccounts.Next() = 0;
+ end;
+
+ // Sort by account name
+ TempFileAccount.SetCurrentKey(Name);
+ end;
+
+ procedure DeleteAccounts(var FileAccountsToDelete: Record "File Account")
+ var
+ CurrentDefaultFileAccount: Record "File Account";
+ ConfirmManagement: Codeunit "Confirm Management";
+ FileScenario: Codeunit "File Scenario";
+ FileConnector: Interface "File System Connector";
+ begin
+ CheckPermissions();
+
+ if not ConfirmManagement.GetResponseOrDefault(ConfirmDeleteQst, true) then
+ exit;
+
+ if not FileAccountsToDelete.FindSet() then
+ exit;
+
+ // Get the current default account to track if it was deleted
+ FileScenario.GetDefaultFileAccount(CurrentDefaultFileAccount);
+
+ // Delete all selected acounts
+ repeat
+ // Check to validate that the connector is still installed
+ // The connector could have been uninstalled by another user/session
+ if IsValidConnector(FileAccountsToDelete.Connector) then begin
+ FileConnector := FileAccountsToDelete.Connector;
+ FileConnector.DeleteAccount(FileAccountsToDelete."Account Id");
+ end;
+ until FileAccountsToDelete.Next() = 0;
+
+ HandleDefaultAccountDeletion(CurrentDefaultFileAccount."Account Id", CurrentDefaultFileAccount.Connector);
+ end;
+
+ local procedure HandleDefaultAccountDeletion(CurrentDefaultAccountId: Guid; Connector: Enum "File System Connector")
+ var
+ AllFileAccounts: Record "File Account";
+ NewDefaultFileAccount: Record "File Account";
+ FileScenario: Codeunit "File Scenario";
+ begin
+ GetAllAccounts(false, AllFileAccounts);
+
+ if AllFileAccounts.IsEmpty() then
+ exit; //All of the accounts were deleted, nothing to do
+
+ if AllFileAccounts.Get(CurrentDefaultAccountId, Connector) then
+ exit; // The default account was not deleted or it never existed
+
+ // In case there's only one account, set it as default
+ if AllFileAccounts.Count() = 1 then begin
+ MakeDefault(AllFileAccounts);
+ exit;
+ end;
+
+ Commit(); // Commit the accounts deletion in order to prompt for new default account
+ if PromptNewDefaultAccountChoice(NewDefaultFileAccount) then
+ MakeDefault(NewDefaultFileAccount)
+ else
+ FileScenario.UnassignScenario(Enum::"File Scenario"::Default); // remove the default scenario as it is pointing to a non-existent account
+ end;
+
+ local procedure PromptNewDefaultAccountChoice(var NewDefaultFileAccount: Record "File Account"): Boolean
+ var
+ FileAccountsPage: Page "File Accounts";
+ begin
+ FileAccountsPage.LookupMode(true);
+ FileAccountsPage.EnableLookupMode();
+ FileAccountsPage.Caption(ChooseNewDefaultTxt);
+ if FileAccountsPage.RunModal() = Action::LookupOK then begin
+ FileAccountsPage.GetAccount(NewDefaultFileAccount);
+ exit(true);
+ end;
+
+ exit(false);
+ end;
+
+ local procedure ImportLogo(var FileAccount: Record "File Account"; Connector: Interface "File System Connector")
+ var
+ FileConnectorLogo: Record "File System Connector Logo";
+ TempBlob: Codeunit "Temp Blob";
+ Base64Convert: Codeunit "Base64 Convert";
+ ConnectorLogoBase64: Text;
+ OutStream: Outstream;
+ InStream: InStream;
+ ConnectorLogoDescriptionTxt: Label '%1 Logo', Locked = true;
+ begin
+ ConnectorLogoBase64 := Connector.GetLogoAsBase64();
+
+ if ConnectorLogoBase64 = '' then
+ exit;
+ if not FileConnectorLogo.Get(FileAccount.Connector) then begin
+ TempBlob.CreateOutStream(OutStream);
+ Base64Convert.FromBase64(ConnectorLogoBase64, OutStream);
+ TempBlob.CreateInStream(InStream);
+ FileConnectorLogo.Connector := FileAccount.Connector;
+ FileConnectorLogo.Logo.ImportStream(InStream, StrSubstNo(ConnectorLogoDescriptionTxt, FileAccount.Connector));
+ if FileConnectorLogo.Insert() then;
+ end;
+ FileAccount.Logo := FileConnectorLogo.Logo
+ end;
+
+ procedure IsAnyAccountRegistered(): Boolean
+ var
+ FileAccount: Record "File Account";
+ begin
+ GetAllAccounts(false, FileAccount);
+
+ exit(not FileAccount.IsEmpty());
+ end;
+
+ internal procedure IsUserFileAdmin(): Boolean
+ var
+ FileScenario: Record "File Scenario";
+ begin
+ exit(FileScenario.WritePermission());
+ end;
+
+ procedure FindAllConnectors(var FileConnector: Record "File System Connector")
+ var
+ Base64Convert: Codeunit "Base64 Convert";
+ ConnectorInterface: Interface "File System Connector";
+ Connector: Enum "File System Connector";
+ ConnectorLogoBase64: Text;
+ OutStream: Outstream;
+ begin
+ foreach Connector in Enum::"File System Connector".Ordinals() do begin
+ ConnectorInterface := Connector;
+ ConnectorLogoBase64 := ConnectorInterface.GetLogoAsBase64();
+ FileConnector.Connector := Connector;
+ FileConnector.Description := ConnectorInterface.GetDescription();
+ if ConnectorLogoBase64 <> '' then begin
+ FileConnector.Logo.CreateOutStream(OutStream);
+ Base64Convert.FromBase64(ConnectorLogoBase64, OutStream);
+ end;
+ FileConnector.Insert();
+ end;
+ end;
+
+ procedure IsValidConnector(Connector: Enum "File System Connector"): Boolean
+ begin
+ exit("File System Connector".Ordinals().Contains(Connector.AsInteger()));
+ end;
+
+ procedure MakeDefault(var FileAccount: Record "File Account")
+ var
+ FileScenario: Codeunit "File Scenario";
+ begin
+ CheckPermissions();
+
+ if IsNullGuid(FileAccount."Account Id") then
+ exit;
+
+ FileScenario.SetDefaultFileAccount(FileAccount);
+ end;
+
+ procedure BrowseAccount(var FileAccount: Record "File Account")
+ var
+ FileAccountBrowser: Page "File Account Browser";
+ begin
+ CheckPermissions();
+
+ if IsNullGuid(FileAccount."Account Id") then
+ exit;
+
+ FileAccountBrowser.SetFileAcconut(FileAccount);
+ FileAccountBrowser.BrowseFileAccount('');
+ FileAccountBrowser.Run();
+ end;
+
+ internal procedure CheckPermissions()
+ begin
+ if not IsUserFileAdmin() then
+ Error(CannotManageSetupErr);
+ end;
+
+ local procedure ImportLogoBlob(var FileAccount: Record "File Account"; Connector: Interface "File System Connector")
+ var
+ Base64Convert: Codeunit "Base64 Convert";
+ ConnectorLogoBase64: Text;
+ OutStream: Outstream;
+ begin
+ ConnectorLogoBase64 := Connector.GetLogoAsBase64();
+
+ if ConnectorLogoBase64 <> '' then begin
+ FileAccount.LogoBlob.CreateOutStream(OutStream);
+ Base64Convert.FromBase64(ConnectorLogoBase64, OutStream);
+ end;
+ end;
+
+ [InternalEvent(false)]
+ internal procedure OnAfterSetSelectionFilter(var FileAccount: Record "File Account")
+ begin
+ end;
+
+ var
+ ConfirmDeleteQst: Label 'Go ahead and delete?';
+ ChooseNewDefaultTxt: Label 'Choose a Default Account';
+ CannotManageSetupErr: Label 'Your user account does not give you permission to set up file. Please contact your administrator.';
+}
\ No newline at end of file
diff --git a/src/System Application/App/File System/src/Account/FileAccountWizard.Page.al b/src/System Application/App/File System/src/Account/FileAccountWizard.Page.al
new file mode 100644
index 0000000000..f18e1bad57
--- /dev/null
+++ b/src/System Application/App/File System/src/Account/FileAccountWizard.Page.al
@@ -0,0 +1,528 @@
+// ------------------------------------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License. See License.txt in the project root for license information.
+// ------------------------------------------------------------------------------------------------
+
+namespace System.FileSystem;
+
+using System.Apps;
+using System.Environment;
+using System.Telemetry;
+
+///
+/// Step by step guide for adding a new file account in Business Central
+///
+page 70001 "File Account Wizard"
+{
+ PageType = NavigatePage;
+ ApplicationArea = All;
+ UsageCategory = Administration;
+ Caption = 'Set Up File';
+ SourceTable = "File System Connector";
+ SourceTableTemporary = true;
+ InsertAllowed = false;
+ ModifyAllowed = false;
+ DeleteAllowed = false;
+ Editable = true;
+ ShowFilter = false;
+ LinksAllowed = false;
+ Permissions = tabledata Media = r,
+ tabledata "Media Resources" = r;
+
+ layout
+ {
+ area(Content)
+ {
+
+ group(Done)
+ {
+ Editable = false;
+ ShowCaption = false;
+ Visible = not DoneVisible and TopBannerVisible;
+ field(NotDoneIcon; MediaResourcesStandard."Media Reference")
+ {
+ ApplicationArea = All;
+ Editable = false;
+ ShowCaption = false;
+ ToolTip = ' ';
+ Caption = ' ';
+ }
+ }
+ group(NotDone)
+ {
+ Editable = false;
+ ShowCaption = false;
+ Visible = DoneVisible and TopBannerVisible;
+ field(DoneIcon; MediaResourcesDone."Media Reference")
+ {
+ ApplicationArea = All;
+ Editable = false;
+ ShowCaption = false;
+ ToolTip = ' ';
+ Caption = ' ';
+ }
+ }
+
+ group(Header)
+ {
+ ShowCaption = false;
+ Visible = WelcomeVisible;
+
+ group(HeaderText)
+ {
+ Caption = 'Welcome to file in Business Central';
+ InstructionalText = 'Make file communications easier by connecting file accounts to Business Central. For example, store sales quotes and orders pdfs without opening an file app.';
+ }
+
+ field(LearnMoreHeader; LearnMoreTok)
+ {
+ ApplicationArea = All;
+ Editable = false;
+ ShowCaption = false;
+ Caption = ' ';
+ ToolTip = 'View information about how to set up the file capabilities.';
+
+ trigger OnDrillDown()
+ begin
+ Hyperlink(LearnMoreURLTxt);
+ end;
+ }
+
+ group(Privacy)
+ {
+ Caption = 'Privacy notice';
+ InstructionalText = 'By adding an file account you acknowledge that the file provider might be able to access the data you send in files from Business Central.';
+ }
+
+ group(GetStartedText)
+ {
+ Caption = 'Let''s go!';
+ InstructionalText = 'Choose Next to get started.';
+ }
+ }
+
+ group(ConnectorHeader)
+ {
+ ShowCaption = false;
+ Visible = ChooseConnectorVisible and ConnectorsAvailable;
+
+ label(UsageWarning)
+ {
+ Caption = 'Use caution when adding file accounts. Depending on your setup, accounts can be available to all users.';
+ }
+ }
+
+ group(ConnectorsGroup)
+ {
+ Visible = ChooseConnectorVisible and ConnectorsAvailable;
+ label("Specify the type of file account to add")
+ {
+ Caption = 'Specify the type of file account to add';
+ ApplicationArea = All;
+ }
+
+ repeater(Connectors)
+ {
+ ShowCaption = false;
+ Visible = ChooseConnectorVisible and ConnectorsAvailable;
+ FreezeColumn = Name;
+ Editable = false;
+
+ field(Logo; Rec.Logo)
+ {
+ ApplicationArea = All;
+ Caption = ' ';
+ Editable = false;
+ Visible = ChooseConnectorVisible;
+ ToolTip = 'Select the type of account you want to create.';
+ ShowCaption = false;
+ Width = 1;
+ }
+
+ field(Name; Rec.Connector)
+ {
+ ApplicationArea = All;
+ Caption = 'Account Type';
+ ToolTip = 'Specifies the type of the account you want to create.';
+ Editable = false;
+ }
+
+ field(Details; Rec.Description)
+ {
+ ApplicationArea = All;
+ Caption = 'Details';
+ ToolTip = 'Specifies more details about the account type.';
+ Editable = false;
+ Width = 50;
+ }
+ }
+ }
+
+ group(NoConnectrosAvailableGroup)
+ {
+ Visible = ChooseConnectorVisible and not ConnectorsAvailable;
+ label(NoConnectorsAvailable)
+ {
+ ApplicationArea = All;
+ Caption = 'There are no file apps available. To use this feature you must install an file app.';
+ }
+
+ label(NoConnectorsAvailable2)
+ {
+ ApplicationArea = All;
+ Caption = 'File apps are available in Extension Management and AppSource.';
+ }
+
+ field(ExtensionManagement; ExtensionManagementTok)
+ {
+ ApplicationArea = All;
+ Editable = false;
+ ShowCaption = false;
+ Caption = ' ';
+ ToolTip = 'Navigate to Extension Management page.';
+
+ trigger OnDrillDown()
+ begin
+ Page.Run(Page::"Extension Management");
+ end;
+ }
+
+ field(AppSource; AppSourceTok)
+ {
+ ApplicationArea = All;
+ Editable = false;
+ ShowCaption = false;
+ Visible = AppSourceAvailable;
+ Caption = ' ';
+ ToolTip = 'Navigate to AppSource.';
+
+ trigger OnDrillDown()
+ begin
+ //FIXME
+ /*
+ AppSource := AppSource.Create();
+ AppSource.ShowAppSource();
+ */
+ end;
+ }
+
+ label(NoConnectorsAvailable3)
+ {
+ ApplicationArea = All;
+ Caption = 'View a list of the available file apps';
+ }
+
+ field(LearnMore; LearnMoreTok)
+ {
+ ApplicationArea = All;
+ Editable = false;
+ ShowCaption = false;
+ Caption = ' ';
+ ToolTip = 'View information about how to set up the file capabilities.';
+
+ trigger OnDrillDown()
+ begin
+ Hyperlink(LearnMoreURLTxt);
+ end;
+ }
+ }
+
+ group(LastPage)
+ {
+ Visible = DoneVisible;
+
+ group(AllSet)
+ {
+ Caption = 'Congratulations!';
+ InstructionalText = 'You have successfully added the file account. To check that it is working, send a test file.';
+ }
+
+ group(Account)
+ {
+ Caption = 'Account';
+ field(Namefield; RegisteredAccount.Name)
+ {
+ ApplicationArea = All;
+ Editable = false;
+ Caption = 'Name';
+ ToolTip = 'Specifies the name of the account registered.';
+ }
+ }
+
+ group(Default)
+ {
+ Caption = '';
+
+ field(DefaultField; SetAsDefault)
+ {
+ ApplicationArea = All;
+ Editable = true;
+ Enabled = true;
+ Caption = 'Set as default';
+ ToolTip = 'Use this account for all scenarios for which an account is not specified. Scenarios are processes that involve sending documents or notifications by file.';
+ }
+ }
+ }
+ }
+ }
+
+ actions
+ {
+ area(Processing)
+ {
+
+ action(Cancel)
+ {
+ ApplicationArea = All;
+ Visible = CancelActionVisible;
+ Caption = 'Cancel';
+ ToolTip = 'Cancel';
+ InFooterBar = true;
+ Image = Cancel;
+
+ trigger OnAction()
+ begin
+ CurrPage.Close();
+ end;
+ }
+
+ action(Back)
+ {
+ ApplicationArea = All;
+ Visible = BackActionVisible;
+ Enabled = BackActionEnabled;
+ Caption = 'Back';
+ ToolTip = 'Back';
+ InFooterBar = true;
+ Image = PreviousRecord;
+
+ trigger OnAction()
+ begin
+ NextStep(true);
+ end;
+ }
+
+ action(Next)
+ {
+ ApplicationArea = All;
+ Visible = NextActionVisible;
+ Enabled = NextActionEnabled;
+ Caption = 'Next';
+ ToolTip = 'Next';
+ InFooterBar = true;
+ Image = NextRecord;
+
+ trigger OnAction()
+ begin
+ NextStep(false);
+ end;
+ }
+
+ action(Finish)
+ {
+ ApplicationArea = All;
+ Visible = FinishActionVisible;
+ Caption = 'Finish';
+ ToolTip = 'Finish';
+ InFooterBar = true;
+ Image = NextRecord;
+
+ trigger OnAction()
+ var
+ FileAccountImpl: Codeunit "File Account Impl.";
+ begin
+ if SetAsDefault then
+ FileAccountImpl.MakeDefault(RegisteredAccount);
+
+ CurrPage.Close();
+ end;
+ }
+ }
+ }
+
+ trigger OnOpenPage()
+ begin
+ StartTime := CurrentDateTime();
+ end;
+
+ trigger OnQueryClosePage(CloseAction: Action): Boolean
+ var
+ DurationAsInt: Integer;
+ begin
+ DurationAsInt := CurrentDateTime() - StartTime;
+ if Step = Step::Done then
+ Session.LogMessage('0000CTK', StrSubstNo(AccountCreationSuccessfullyCompletedDurationLbl, DurationAsInt), Verbosity::Normal, DataClassification::SystemMetadata, TelemetryScope::ExtensionPublisher, 'Category', FileCategoryLbl)
+ else
+ Session.LogMessage('0000CTL', StrSubstNo(AccountCreationFailureDurationLbl, DurationAsInt), Verbosity::Normal, DataClassification::SystemMetadata, TelemetryScope::ExtensionPublisher, 'Category', FileCategoryLbl);
+ end;
+
+ trigger OnInit()
+ var
+ DefaultAccount: Record "File Account";
+ FileAccountImpl: Codeunit "File Account Impl.";
+ FileScenario: Codeunit "File Scenario";
+ begin
+ FileAccountImpl.CheckPermissions();
+
+ Step := Step::Welcome;
+ SetDefaultControls();
+ ShowWelcomeStep();
+
+ FileAccountImpl.FindAllConnectors(Rec);
+
+ FileRateLimitDisplay := NoLimitTxt;
+
+ if not FileScenario.GetDefaultFileAccount(DefaultAccount) then
+ SetAsDefault := true;
+
+ ConnectorsAvailable := Rec.FindFirst(); // Set the focus on the first record
+ AppSourceAvailable := false; //FIXME AppSource.IsAvailable();
+ LoadTopBanners();
+ end;
+
+ local procedure NextStep(Backwards: Boolean)
+ begin
+ if Backwards then
+ Step -= 1
+ else
+ Step += 1;
+
+ SetDefaultControls();
+
+ case Step of
+ Step::Welcome:
+ ShowWelcomeStep();
+ Step::"Choose Connector":
+ ShowChooseConnectorStep();
+ Step::"Register Account":
+ ShowRegisterAccountStep();
+ Step::"Done":
+ ShowDoneStep();
+ end;
+ end;
+
+ local procedure ShowWelcomeStep()
+ begin
+ WelcomeVisible := true;
+ BackActionEnabled := false;
+ end;
+
+ local procedure ShowChooseConnectorStep()
+ begin
+ if not ConnectorsAvailable then
+ NextActionEnabled := false;
+
+ ChooseConnectorVisible := true;
+ end;
+
+ local procedure ShowRegisterAccountStep()
+ var
+ FeatureTelemetry: Codeunit "Feature Telemetry";
+ DefaultFileRateLimit: Integer;
+ AccountWasRegistered: Boolean;
+ ConnectorSucceeded: Boolean;
+ begin
+ ConnectorSucceeded := TryRegisterAccount(AccountWasRegistered);
+
+ if AccountWasRegistered then begin
+ FeatureTelemetry.LogUptake('0000CTF', 'File Access', Enum::"Feature Uptake Status"::"Set up");
+ Session.LogMessage('0000CTH', Format(Rec.Connector) + ' account has been setup.', Verbosity::Normal, DataClassification::SystemMetadata, TelemetryScope::ExtensionPublisher, 'Category', FileCategoryLbl);
+ NextStep(false);
+ end else begin
+ Session.LogMessage('0000CTI', StrSubstNo(Format(Rec.Connector) + ' account has failed to setup. Error: %1', GetLastErrorCallStack()), Verbosity::Normal, DataClassification::SystemMetadata, TelemetryScope::ExtensionPublisher, 'Category', FileCategoryLbl);
+ NextStep(true);
+ end;
+
+ if not ConnectorSucceeded then
+ Error(GetLastErrorText());
+ end;
+
+ [TryFunction]
+ local procedure TryRegisterAccount(var AccountWasRegistered: Boolean)
+ var
+ FileAccountImpl: Codeunit "File Account Impl.";
+ FileConnector: Interface "File System Connector";
+ begin
+ // Check to validate that the connector is still installed
+ // The connector could have been uninstalled by another user/session
+ if not FileAccountImpl.IsValidConnector(Rec.Connector) then
+ Error(FileConnectorHasBeenUninstalledMsg);
+
+ FileConnector := Rec.Connector;
+
+ ClearLastError();
+ AccountWasRegistered := FileConnector.RegisterAccount(RegisteredAccount);
+ RegisteredAccount.Connector := Rec.Connector;
+ end;
+
+ local procedure ShowDoneStep()
+ begin
+ DoneVisible := true;
+ BackActionVisible := false;
+ NextActionVisible := false;
+ CancelActionVisible := false;
+ FinishActionVisible := true;
+ TestFileActionVisible := true;
+ end;
+
+ local procedure SetDefaultControls()
+ begin
+ // Actions
+ BackActionVisible := true;
+ BackActionEnabled := true;
+ NextActionVisible := true;
+ NextActionEnabled := true;
+ CancelActionVisible := true;
+ FinishActionVisible := false;
+ TestFileActionVisible := false;
+
+ // Groups
+ WelcomeVisible := false;
+ ChooseConnectorVisible := false;
+ DoneVisible := false;
+ end;
+
+ local procedure LoadTopBanners()
+ var
+ AssistedSetupLogoTok: Label 'ASSISTEDSETUP-NOTEXT-400PX.PNG', Locked = true;
+ begin
+ if MediaResourcesStandard.Get(AssistedSetupLogoTok) and
+ MediaResourcesDone.Get(AssistedSetupLogoTok) and (CurrentClientType() = ClientType::Web)
+ then
+ TopBannerVisible := MediaResourcesDone."Media Reference".HasValue();
+ end;
+
+ var
+ RegisteredAccount: Record "File Account";
+ MediaResourcesStandard: Record "Media Resources";
+ MediaResourcesDone: Record "Media Resources";
+ //FIXME [RunOnClient]
+ //FIXME AppSource: DotNet AppSource;
+ Step: Option Welcome,"Choose Connector","Register Account",Done;
+ RateLimit: Integer;
+ AppSourceTok: Label 'AppSource';
+ ExtensionManagementTok: Label 'Extension Management';
+ FileCategoryLbl: Label 'File', Locked = true;
+ LearnMoreURLTxt: Label 'https://go.microsoft.com/fwlink/?linkid=2134520', Locked = true; //FIXME
+ LearnMoreTok: Label 'Learn more';
+ NoLimitTxt: Label 'No limit';
+ AccountCreationSuccessfullyCompletedDurationLbl: Label 'Successful creation of account completed. Duration: %1 milliseconds.', Comment = '%1 - Duration', Locked = true;
+ AccountCreationFailureDurationLbl: Label 'Creation of account failed. Duration: %1 milliseconds.', Comment = '%1 - Duration', Locked = true;
+ FileConnectorHasBeenUninstalledMsg: Label 'The selected file extension has been uninstalled. You must reinstall the extension to add an account with it.';
+ AppSourceAvailable: Boolean;
+ TopBannerVisible: Boolean;
+ BackActionVisible: Boolean;
+ BackActionEnabled: Boolean;
+ NextActionVisible: Boolean;
+ NextActionEnabled: Boolean;
+ CancelActionVisible: Boolean;
+ FinishActionVisible: Boolean;
+ TestFileActionVisible: Boolean;
+ WelcomeVisible: Boolean;
+ ChooseConnectorVisible: Boolean;
+ DoneVisible: Boolean;
+ ConnectorsAvailable: Boolean;
+ SetAsDefault: Boolean;
+ StartTime: DateTime;
+ FileRateLimitDisplay: Text[250];
+}
\ No newline at end of file
diff --git a/src/System Application/App/File System/src/Account/FileAccounts.Page.al b/src/System Application/App/File System/src/Account/FileAccounts.Page.al
new file mode 100644
index 0000000000..d069d9836c
--- /dev/null
+++ b/src/System Application/App/File System/src/Account/FileAccounts.Page.al
@@ -0,0 +1,332 @@
+// ------------------------------------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License. See License.txt in the project root for license information.
+// ------------------------------------------------------------------------------------------------
+
+namespace System.FileSystem;
+
+using System.Telemetry;
+
+///
+/// Lists all of the registered file accounts
+///
+page 70000 "File Accounts"
+{
+ PageType = List;
+ Caption = 'File Accounts';
+ ApplicationArea = All;
+ UsageCategory = Administration;
+ SourceTable = "File Account";
+ SourceTableTemporary = true;
+ PromotedActionCategories = 'New,Process,Report,Navigate';
+ InsertAllowed = false;
+ ModifyAllowed = false;
+ DeleteAllowed = false;
+ Editable = false;
+ ShowFilter = false;
+ LinksAllowed = false;
+ RefreshOnActivate = true;
+
+ layout
+ {
+ area(Content)
+ {
+ repeater(Accounts)
+ {
+ Visible = ShowLogo;
+ FreezeColumn = NameField;
+ field(LogoField; Rec.LogoBlob)
+ {
+ ApplicationArea = All;
+ ShowCaption = false;
+ Caption = ' ';
+ Visible = ShowLogo;
+ ToolTip = 'Specifies the logo for the type of file account.';
+ Width = 1;
+ }
+
+ field(NameField; Rec.Name)
+ {
+ ApplicationArea = All;
+ ToolTip = 'Specifies the name of the account.';
+ Visible = not IsInLookupMode;
+
+ trigger OnDrillDown()
+ begin
+ ShowAccountInformation();
+ end;
+ }
+
+ field(NameFieldLookup; Rec.Name)
+ {
+ ApplicationArea = All;
+ ToolTip = 'Specifies the name of the account.';
+ Visible = IsInLookupMode;
+ }
+
+ field(DefaultField; DefaultTxt)
+ {
+ ApplicationArea = All;
+ Caption = 'Default';
+ ToolTip = 'Specifies whether the file account will be used for all scenarios for which an account is not specified. You must have a default file account, even if you have only one account.';
+ Visible = not IsInLookupMode;
+ }
+
+ field(FileConnector; Rec.Connector)
+ {
+ ApplicationArea = All;
+ ToolTip = 'Specifies the type of file extension that the account is added to.';
+ Visible = false;
+ }
+ }
+ }
+
+ area(factboxes)
+ {
+ part(Scenarios; "File Scenarios FactBox")
+ {
+ Caption = 'File Scenarios';
+ SubPageLink = "Account Id" = field("Account Id"), Connector = field(Connector), Scenario = filter(<> 0); // Do not show Default scenario
+ ApplicationArea = All;
+ }
+ }
+ }
+
+ actions
+ {
+ area(Creation)
+ {
+ action(View)
+ {
+ ApplicationArea = All;
+ Image = View;
+ ToolTip = 'View settings for the file account.';
+ ShortcutKey = return;
+ Visible = false;
+
+ trigger OnAction()
+ begin
+ ShowAccountInformation();
+ end;
+ }
+
+ action(AddAccount)
+ {
+ ApplicationArea = All;
+ Promoted = true;
+ PromotedOnly = true;
+ PromotedCategory = New;
+ Image = Add;
+ Caption = 'Add an file account';
+ ToolTip = 'Add an file account.';
+ Visible = (not IsInLookupMode) and CanUserManageFileSetup;
+
+ trigger OnAction()
+ begin
+ Page.RunModal(Page::"File Account Wizard");
+
+ UpdateFileAccounts();
+ end;
+ }
+ }
+
+ area(Processing)
+ {
+ action(MakeDefault)
+ {
+ ApplicationArea = All;
+ Image = Default;
+ Caption = 'Set as default';
+ ToolTip = 'Mark the selected file account as the default account. This account will be used for all scenarios for which an account is not specified.';
+ Visible = (not IsInLookupMode) and CanUserManageFileSetup;
+ Promoted = true;
+ PromotedOnly = true;
+ PromotedCategory = Process;
+ PromotedIsBig = true;
+ Scope = Repeater;
+ Enabled = not IsDefault;
+
+ trigger OnAction()
+ begin
+ FileAccountImpl.MakeDefault(Rec);
+
+ UpdateAccounts := true;
+ CurrPage.Update(false);
+ end;
+ }
+ action(BrowseAccount)
+ {
+ ApplicationArea = All;
+ Image = SelectField;
+ Caption = 'Browse Account';
+ ToolTip = 'Opens a File Browser and shows the content of the selected account.';
+ Visible = (not IsInLookupMode) and CanUserManageFileSetup;
+ Promoted = true;
+ PromotedOnly = true;
+ PromotedCategory = Process;
+ PromotedIsBig = true;
+ Scope = Repeater;
+
+ trigger OnAction()
+ begin
+ FileAccountImpl.BrowseAccount(Rec);
+
+ UpdateAccounts := true;
+ CurrPage.Update(false);
+ end;
+ }
+
+ action(Delete)
+ {
+ ApplicationArea = All;
+ Promoted = true;
+ PromotedOnly = true;
+ PromotedCategory = Process;
+ Image = Delete;
+ Caption = 'Delete file account';
+ ToolTip = 'Delete the file account.';
+ Visible = (not IsInLookupMode) and CanUserManageFileSetup;
+ Scope = Repeater;
+
+ trigger OnAction()
+ begin
+ CurrPage.SetSelectionFilter(Rec);
+ FileAccountImpl.OnAfterSetSelectionFilter(Rec);
+
+ FileAccountImpl.DeleteAccounts(Rec);
+
+ UpdateFileAccounts();
+ end;
+ }
+ }
+
+ area(Navigation)
+ {
+ action(FileScenarioSetup)
+ {
+ ApplicationArea = All;
+ Promoted = true;
+ PromotedOnly = true;
+ PromotedCategory = Category4;
+ Image = Answers;
+ Caption = 'File Scenarios';
+ ToolTip = 'Assign scenarios to the file accounts.';
+ Visible = not IsInLookupMode;
+
+ trigger OnAction()
+ var
+ FileScenarioSetup: Page "File Scenario Setup";
+ begin
+ FileScenarioSetup.SetFileAccountId(Rec."Account Id", Rec.Connector);
+ FileScenarioSetup.Run();
+ end;
+ }
+ }
+ }
+
+ trigger OnOpenPage()
+ var
+ FeatureTelemetry: Codeunit "Feature Telemetry";
+ begin
+ FeatureTelemetry.LogUptake('0000CTA', 'Fileing', Enum::"Feature Uptake Status"::Discovered);
+ CanUserManageFileSetup := FileAccountImpl.IsUserFileAdmin();
+ Rec.SetCurrentKey("Account Id", Connector);
+ UpdateFileAccounts();
+ ShowLogo := true;
+ end;
+
+ trigger OnAfterGetRecord()
+ begin
+ // Updating the accounts is done via OnAfterGetRecord in the cases when an account was changed from the corresponding connector's page
+ if UpdateAccounts then begin
+ UpdateAccounts := false;
+ UpdateFileAccounts();
+ end;
+
+ DefaultTxt := '';
+
+ IsDefault := DefaultFileAccount."Account Id" = Rec."Account Id";
+ if IsDefault then
+ DefaultTxt := '✓';
+ end;
+
+ local procedure UpdateFileAccounts()
+ var
+ FileAccount: Codeunit "File Account";
+ FileScenario: Codeunit "File Scenario";
+ IsSelected: Boolean;
+ SelectedAccountId: Guid;
+ begin
+ // We need this code block to maintain the same selected record.
+ SelectedAccountId := Rec."Account Id";
+ IsSelected := not IsNullGuid(SelectedAccountId);
+
+ FileAccount.GetAllAccounts(true, Rec); // Refresh the file accounts
+ FileScenario.GetDefaultFileAccount(DefaultFileAccount); // Refresh the default file account
+
+ if IsSelected then begin
+ Rec."Account Id" := SelectedAccountId;
+ if Rec.Find() then;
+ end else
+ if Rec.FindFirst() then;
+
+ HasFileAccount := not Rec.IsEmpty();
+
+ CurrPage.Update(false);
+ end;
+
+ local procedure ShowAccountInformation()
+ var
+ FileAccountImpl: Codeunit "File Account Impl.";
+ Connector: Interface "File System Connector";
+ begin
+ UpdateAccounts := true;
+
+#pragma warning disable AL0603
+ if not FileAccountImpl.IsValidConnector(Rec.Connector.AsInteger()) then
+#pragma warning restore AL0603
+ Error(FileConnectorHasBeenUninstalledMsg);
+
+ Connector := Rec.Connector;
+ Connector.ShowAccountInformation(Rec."Account Id");
+ end;
+
+ ///
+ /// Gets the selected file account.
+ ///
+ /// The selected file account
+ procedure GetAccount(var FileAccount: Record "File Account")
+ begin
+ FileAccount := Rec;
+ end;
+
+ ///
+ /// Sets an file account to be selected.
+ ///
+ /// The file account to be initially selected on the page
+ procedure SetAccount(var FileAccount: Record "File Account")
+ begin
+ Rec := FileAccount;
+ end;
+
+ ///
+ /// Enables the lookup mode on the page.
+ ///
+ procedure EnableLookupMode()
+ begin
+ IsInLookupMode := true;
+ CurrPage.LookupMode(true);
+ end;
+
+ var
+ DefaultFileAccount: Record "File Account";
+ FileAccountImpl: Codeunit "File Account Impl.";
+ IsDefault: Boolean;
+ CanUserManageFileSetup: Boolean;
+ DefaultTxt: Text;
+ UpdateAccounts: Boolean;
+ ShowLogo: Boolean;
+ IsInLookupMode: Boolean;
+ HasFileAccount: Boolean;
+ FileConnectorHasBeenUninstalledMsg: Label 'The selected file extension has been uninstalled. To view information about the file account, you must reinstall the extension.';
+}
\ No newline at end of file
diff --git a/src/System Application/App/File System/src/Connector/FileSystemConnector.Enum.al b/src/System Application/App/File System/src/Connector/FileSystemConnector.Enum.al
new file mode 100644
index 0000000000..7cd7562bf2
--- /dev/null
+++ b/src/System Application/App/File System/src/Connector/FileSystemConnector.Enum.al
@@ -0,0 +1,14 @@
+// ------------------------------------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License. See License.txt in the project root for license information.
+// ------------------------------------------------------------------------------------------------
+
+namespace System.FileSystem;
+
+///
+/// Enum that holds all of the available file connectors.
+///
+enum 70000 "File System Connector" implements "File System Connector"
+{
+ Extensible = true;
+}
\ No newline at end of file
diff --git a/src/System Application/App/File System/src/Connector/FileSystemConnector.Interface.al b/src/System Application/App/File System/src/Connector/FileSystemConnector.Interface.al
new file mode 100644
index 0000000000..d0a1316638
--- /dev/null
+++ b/src/System Application/App/File System/src/Connector/FileSystemConnector.Interface.al
@@ -0,0 +1,148 @@
+// ------------------------------------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License. See License.txt in the project root for license information.
+// ------------------------------------------------------------------------------------------------
+
+namespace System.FileSystem;
+
+///
+/// An File System Connector interface used to creating file accounts and handle external files.
+///
+interface "File System Connector"
+{
+ ///
+ /// Gets a List of Files stored on the provided account.
+ ///
+ /// The file account ID which is used to get the file.
+ /// The file path to list.
+ /// Defines the pagination data.
+ /// A list with all files stored in the path.
+ procedure ListFiles(AccountId: Guid; Path: Text; FilePaginationData: Codeunit "File Pagination Data"; var FileAccountContent: Record "File Account Content" temporary);
+
+ ///
+ /// Gets a file from the provided account.
+ ///
+ /// The file account ID which is used to get the file.
+ /// The file path inside the file account.
+ /// The Stream were the file is read to.
+ procedure GetFile(AccountId: Guid; Path: Text; Stream: InStream);
+
+ ///
+ /// Gets a file to the provided account.
+ ///
+ /// The file account ID which is used to send out the file.
+ /// The file path inside the file account.
+ /// The Stream were the file is read from.
+ procedure SetFile(AccountId: Guid; Path: Text; Stream: InStream);
+
+
+ ///
+ /// Copies as file inside the provided account.
+ ///
+ /// The file account ID which is used to send out the file.
+ /// The source file path.
+ /// The target file path.
+ procedure CopyFile(AccountId: Guid; SourcePath: Text; TargetPath: Text);
+
+
+ ///
+ /// Move as file inside the provided account.
+ ///
+ /// The file account ID which is used to send out the file.
+ /// The source file path.
+ /// The target file path.
+ procedure MoveFile(AccountId: Guid; SourcePath: Text; TargetPath: Text);
+
+ ///
+ /// Checks if a file exists on the provided account.
+ ///
+ /// The file account ID which is used to send out the file.
+ /// The file path inside the file account.
+ /// Returns true if the file exists
+ procedure FileExists(AccountId: Guid; Path: Text): Boolean;
+
+ ///
+ /// Deletes a file exists on the provided account.
+ ///
+ /// The file account ID which is used to send out the file.
+ /// The file path inside the file account.
+ procedure DeleteFile(AccountId: Guid; Path: Text);
+
+ ///
+ /// Gets a List of Directories stored on the provided account.
+ ///
+ /// The file account ID which is used to get the file.
+ /// The file path to list.
+ /// Defines the pagination data.
+ /// A list with all directories stored in the path.
+ procedure ListDirectories(AccountId: Guid; Path: Text; FilePaginationData: Codeunit "File Pagination Data"; var FileAccountContent: Record "File Account Content" temporary);
+
+ ///
+ /// Creates a directory on the provided account.
+ ///
+ /// The directory path inside the file account.
+ /// The file account ID which is used to send out the file.
+ procedure CreateDirectory(AccountId: Guid; Path: Text);
+
+ ///
+ /// Checks if a directory exists on the provided account.
+ ///
+ /// The file account ID which is used to send out the file.
+ /// The directory path inside the file account.
+ /// Returns true if the directory exists
+ procedure DirectoryExists(AccountId: Guid; Path: Text): Boolean;
+
+ ///
+ /// Deletes a directory exists on the provided account.
+ ///
+ /// The file account ID which is used to send out the file.
+ /// The directory path inside the file account.
+ procedure DeleteDirectory(AccountId: Guid; Path: Text);
+
+ ///
+ /// Returns the path separator of the file account.
+ ///
+ /// The Path separator like / or \
+ procedure PathSeparator(): Text;
+
+ ///
+ /// Gets the file accounts registered for the connector.
+ ///
+ /// Out variable that holds the registered file accounts for the connector.
+ procedure GetAccounts(var Accounts: Record "File Account");
+
+ ///
+ /// Shows the information for an file account.
+ ///
+ /// The ID of the file account
+ procedure ShowAccountInformation(AccountId: Guid);
+
+ ///
+ /// Registers an file account for the connector.
+ ///
+ /// The out parameter must hold the account ID of the added account.
+ /// Out parameter with the details of the registered Account.
+ /// True if an account was registered.
+ procedure RegisterAccount(var FileAccount: Record "File Account"): Boolean
+
+ ///
+ /// Deletes an file account for the connector.
+ ///
+ /// The ID of the file account
+ /// True if an account was deleted.
+ procedure DeleteAccount(AccountId: Guid): Boolean
+
+ ///
+ /// Provides a custom logo for the connector that shows in the Setup File Account Guide.
+ ///
+ /// Base64 encoded image.
+ /// The recomended image size is 128x128.
+ /// The logo of the connector is Base64 format
+ procedure GetLogoAsBase64(): Text;
+
+ ///
+ /// Provides a more detailed description of the connector.
+ ///
+ /// A more detailed description of the connector.
+ procedure GetDescription(): Text[250];
+}
\ No newline at end of file
diff --git a/src/System Application/App/File System/src/Connector/FileSystemConnector.Table.al b/src/System Application/App/File System/src/Connector/FileSystemConnector.Table.al
new file mode 100644
index 0000000000..6795e622f2
--- /dev/null
+++ b/src/System Application/App/File System/src/Connector/FileSystemConnector.Table.al
@@ -0,0 +1,39 @@
+// ------------------------------------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License. See License.txt in the project root for license information.
+// ------------------------------------------------------------------------------------------------
+
+namespace System.FileSystem;
+
+table 70001 "File System Connector"
+{
+ TableType = Temporary;
+ Access = Internal;
+ InherentPermissions = X;
+ InherentEntitlements = X;
+
+ fields
+ {
+ field(1; Connector; Enum "File System Connector")
+ {
+ DataClassification = SystemMetadata;
+ }
+ field(2; Logo; Blob)
+ {
+ DataClassification = SystemMetadata;
+ Subtype = Bitmap;
+ }
+ field(3; Description; Text[250])
+ {
+ DataClassification = SystemMetadata;
+ }
+ }
+
+ keys
+ {
+ key(PK; Connector)
+ {
+ Clustered = true;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/System Application/App/File System/src/Connector/FileSystemConnectorLogo.Table.al b/src/System Application/App/File System/src/Connector/FileSystemConnectorLogo.Table.al
new file mode 100644
index 0000000000..6d3459eea1
--- /dev/null
+++ b/src/System Application/App/File System/src/Connector/FileSystemConnectorLogo.Table.al
@@ -0,0 +1,35 @@
+// ------------------------------------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License. See License.txt in the project root for license information.
+// ------------------------------------------------------------------------------------------------
+
+namespace System.FileSystem;
+
+table 70002 "File System Connector Logo"
+{
+ DataClassification = SystemMetadata;
+ Access = Internal;
+ InherentPermissions = X;
+ InherentEntitlements = X;
+
+ fields
+ {
+ field(1; Connector; Enum "File System Connector")
+ {
+ DataClassification = SystemMetadata;
+ }
+ field(2; Logo; Media)
+ {
+ DataClassification = CustomerContent;
+ }
+ }
+
+ keys
+ {
+ key(PK; Connector)
+ {
+ Clustered = true;
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/src/System Application/App/File System/src/FileSystem/FileSystem.Codeunit.al b/src/System Application/App/File System/src/FileSystem/FileSystem.Codeunit.al
new file mode 100644
index 0000000000..41a19f67d8
--- /dev/null
+++ b/src/System Application/App/File System/src/FileSystem/FileSystem.Codeunit.al
@@ -0,0 +1,258 @@
+// ------------------------------------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License. See License.txt in the project root for license information.
+// ------------------------------------------------------------------------------------------------
+
+namespace System.FileSystem;
+
+codeunit 70004 "File System"
+{
+ var
+ FileSystemImpl: Codeunit "File System Impl.";
+
+ ///
+ /// Initialized the File System for the give scenario.
+ ///
+ /// File Scenario to use.
+ procedure Initialize(Scenario: Enum "File Scenario")
+ begin
+ FileSystemImpl.Initialize(Scenario);
+ end;
+
+ ///
+ /// Initialized the File System for the give file account.
+ ///
+ /// File Account to use.
+ procedure Initialize(FileAccount: Record "File Account")
+ begin
+ FileSystemImpl.Initialize(FileAccount);
+ end;
+
+ ///
+ /// List all files from the given path.
+ ///
+ /// Folder to list
+ /// Defines the pagination data.
+ /// File account content.
+ procedure ListFiles(Path: Text; FilePaginationData: Codeunit "File Pagination Data"; var FileAccountContent: Record "File Account Content" temporary)
+ begin
+ FileSystemImpl.ListFiles(Path, FilePaginationData, FileAccountContent);
+ end;
+
+ ///
+ /// Retireves a file from the file account.
+ ///
+ /// File Path to open.
+ /// Stream which contains the file content.
+ [TryFunction]
+ procedure GetFile(Path: Text; Stream: InStream)
+ begin
+ FileSystemImpl.GetFile(Path, Stream);
+ end;
+
+ ///
+ /// Stores a file in to the file account.
+ ///
+ /// File Path inside the file account.
+ /// Stream to store.
+ [TryFunction]
+ procedure SetFile(Path: Text; Stream: InStream)
+ begin
+ FileSystemImpl.SetFile(Path, Stream);
+ end;
+
+ ///
+ /// Copies a file in the file account.
+ ///
+ /// Source path of the file.
+ /// Target Path of the file copy.
+ [TryFunction]
+ procedure CopyFile(SourcePath: Text; TargetPath: Text)
+ begin
+ FileSystemImpl.CopyFile(SourcePath, TargetPath);
+ end;
+
+ ///
+ /// Moves a file in the file account.
+ ///
+ /// Source path of the file.
+ /// Target Path of the file.
+ [TryFunction]
+ procedure MoveFile(SourcePath: Text; TargetPath: Text)
+ begin
+ FileSystemImpl.MoveFile(SourcePath, TargetPath);
+ end;
+
+ ///
+ /// Checks if a specific file exists in the file account.
+ ///
+ /// File path to check.
+ /// Returns true if the file exists.
+ procedure FileExists(Path: Text): Boolean
+ begin
+ exit(FileSystemImpl.FileExists(Path));
+ end;
+
+ ///
+ /// Deletes a file from the file account.
+ ///
+ /// File path of the file to delete.
+ [TryFunction]
+ procedure DeleteFile(Path: Text)
+ begin
+ FileSystemImpl.DeleteFile(Path);
+ end;
+
+ ///
+ /// List all directories from the given path.
+ ///
+ /// Folder to list
+ /// Defines the pagination data.
+ /// File account content.
+ [TryFunction]
+ procedure ListDirectories(Path: Text; FilePaginationData: Codeunit "File Pagination Data"; var FileAccountContent: Record "File Account Content" temporary)
+ begin
+ FileSystemImpl.ListDirectories(Path, FilePaginationData, FileAccountContent);
+ end;
+
+ ///
+ /// Creates a directory in the file account.
+ ///
+ /// Path of the new Directory to create.
+ [TryFunction]
+ procedure CreateDirectory(Path: Text)
+ begin
+ FileSystemImpl.CreateDirectory(Path);
+ end;
+
+ ///
+ /// Checks if a specific directory exists in the file account.
+ ///
+ /// Path of the directry to check.
+ /// Returns true if directory exists.
+ procedure DirectoryExists(Path: Text): Boolean
+ begin
+ exit(FileSystemImpl.DirectoryExists(Path));
+ end;
+
+ ///
+ /// Deletes a directory from the file account.
+ ///
+ /// Directory to remove.
+ [TryFunction]
+ procedure DeleteDirectory(Path: Text)
+ begin
+ FileSystemImpl.DeleteDirectory(Path);
+ end;
+
+ ///
+ /// Returns the path separator used by the file account system.
+ ///
+ ///
+ procedure PathSeparator(): Text
+ begin
+ exit(FileSystemImpl.PathSeparator());
+ end;
+
+ ///
+ /// Combines to paths together.
+ ///
+ /// First part to combine.
+ /// Second part to combine.
+ /// Correctly combined path.
+ procedure CombinePath(Path: Text; ChildPath: Text): Text
+ begin
+ Exit(FileSystemImpl.CombinePath(Path, ChildPath));
+ end;
+
+ ///
+ /// Gets the Parent Path of the given path.
+ ///
+ /// File or directoy path.
+ /// The parent of the speicfied path.
+ procedure GetParentPath(Path: Text): Text
+ begin
+ exit(FileSystemImpl.GetParentPath(Path));
+ end;
+
+ ///
+ /// Opens a folder selection dialog.
+ ///
+ /// Start path of the dialog.
+ /// Returns the selected Folder.
+ procedure SelectFolderUI(Path: Text): Text
+ var
+ DefaulSelectFolderUILbl: Label 'Select a folder';
+ begin
+ exit(SelectFolderUI(Path, DefaulSelectFolderUILbl));
+ end;
+
+ ///
+ /// Opens a folder selection dialog.
+ ///
+ /// Start path of the dialog.
+ /// Title of the selection dialog.
+ /// Returns the selected Folder.
+ procedure SelectFolderUI(Path: Text; DialogTitle: Text): Text
+ begin
+ exit(FileSystemImpl.SelectFolderUI(Path, DialogTitle));
+ end;
+
+ ///
+ /// Opens a select file dialog.
+ ///
+ /// Start path.
+ /// A filter string that applies only on files not on folders.
+ /// Returns the path of the selected file.
+ procedure SelectFileUI(Path: Text; FileFilter: Text): Text
+ var
+ DefaulSelectFileUILbl: Label 'Select a file';
+ begin
+ exit(SelectFileUI(Path, FileFilter, DefaulSelectFileUILbl));
+ end;
+
+ ///
+ /// Opens a select file dialog.
+ ///
+ /// Start path of the dialog.
+ /// A filter string that applies only on files not on folders.
+ /// Title of the selection dialog.
+ /// Returns the path of the selected file.
+ procedure SelectFileUI(Path: Text; FileFilter: Text; DialogTitle: Text): Text
+ begin
+ exit(FileSystemImpl.SelectFileUI(Path, FileFilter, DialogTitle));
+ end;
+
+ ///
+ /// Opens a save to dialog.
+ ///
+ /// Start path of the dialog.
+ /// The fileextion without dot (like pdf or txt).
+ /// Returns the selecte file path.
+ procedure SaveFileUI(Path: Text; FileExtension: Text): Text
+ var
+ DefaultSaveFileUITitleLbl: Label 'Save as';
+ begin
+ exit(SaveFileUI(Path, FileExtension, DefaultSaveFileUITitleLbl));
+ end;
+
+ ///
+ /// Opens a save to dialog.
+ ///
+ /// Start path of the dialog.
+ /// The fileextion without dot (like pdf or txt).
+ /// Title of the selection dialog.
+ /// Returns the selecte file path.
+ procedure SaveFileUI(Path: Text; FileExtension: Text; DialogTitle: Text): Text
+ begin
+ exit(FileSystemImpl.SaveFileUI(Path, FileExtension, DialogTitle));
+ end;
+
+ ///
+ /// Opens a File Browser
+ ///
+ procedure BrowseAccount()
+ begin
+ FileSystemImpl.BrowseAccount();
+ end;
+}
diff --git a/src/System Application/App/File System/src/FileSystem/FileSystemImp.Codeunit.al b/src/System Application/App/File System/src/FileSystem/FileSystemImp.Codeunit.al
new file mode 100644
index 0000000000..c569119e64
--- /dev/null
+++ b/src/System Application/App/File System/src/FileSystem/FileSystemImp.Codeunit.al
@@ -0,0 +1,208 @@
+// ------------------------------------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License. See License.txt in the project root for license information.
+// ------------------------------------------------------------------------------------------------
+
+namespace System.FileSystem;
+
+codeunit 70005 "File System Impl."
+{
+ var
+ IFileConnector: Interface "File System Connector";
+ CurrFileAccount: Record "File Account";
+ Initialized: Boolean;
+
+ internal procedure Initialize(Scenario: Enum "File Scenario")
+ var
+ FileAccount: Record "File Account";
+ FileScenario: Codeunit "File Scenario";
+ NoFileAccountFoundErr: Label 'No defaut file account defined.';
+ begin
+ if not FileScenario.GetFileAccount(Scenario, FileAccount) then
+ Error(NoFileAccountFoundErr);
+
+ Initialize(FileAccount);
+ end;
+
+ internal procedure Initialize(FileAccount: Record "File Account")
+ begin
+ CurrFileAccount := FileAccount;
+ IFileConnector := FileAccount.Connector;
+ Initialized := true;
+ end;
+
+ internal procedure ListFiles(Path: Text; FilePaginationData: Codeunit "File Pagination Data"; var FileAccountContent: Record "File Account Content" temporary)
+ begin
+ CheckInitialization();
+ IFileConnector.ListFiles(CurrFileAccount."Account Id", Path, FilePaginationData, FileAccountContent);
+ end;
+
+ internal procedure GetFile(Path: Text; Stream: InStream)
+ begin
+ CheckInitialization();
+ IFileConnector.GetFile(CurrFileAccount."Account Id", Path, Stream);
+ end;
+
+ internal procedure SetFile(Path: Text; Stream: InStream)
+ begin
+ CheckInitialization();
+ IFileConnector.SetFile(CurrFileAccount."Account Id", Path, Stream);
+ end;
+
+
+ internal procedure CopyFile(SourcePath: Text; TargetPath: Text)
+ begin
+ CheckInitialization();
+ IFileConnector.CopyFile(CurrFileAccount."Account Id", SourcePath, TargetPath);
+ end;
+
+ internal procedure MoveFile(SourcePath: Text; TargetPath: Text)
+ begin
+ CheckInitialization();
+ IFileConnector.MoveFile(CurrFileAccount."Account Id", SourcePath, TargetPath);
+ end;
+
+ internal procedure FileExists(Path: Text): Boolean
+ begin
+ CheckInitialization();
+ exit(IFileConnector.FileExists(CurrFileAccount."Account Id", Path));
+ end;
+
+ internal procedure DeleteFile(Path: Text)
+ begin
+ CheckInitialization();
+ IFileConnector.DeleteFile(CurrFileAccount."Account Id", Path);
+ end;
+
+ internal procedure ListDirectories(Path: Text; FilePaginationData: Codeunit "File Pagination Data"; var FileAccountContent: Record "File Account Content" temporary)
+ begin
+ CheckInitialization();
+ IFileConnector.ListDirectories(CurrFileAccount."Account Id", Path, FilePaginationData, FileAccountContent);
+ end;
+
+ internal procedure CreateDirectory(Path: Text)
+ begin
+ CheckInitialization();
+ IFileConnector.CreateDirectory(CurrFileAccount."Account Id", Path);
+ end;
+
+ internal procedure DirectoryExists(Path: Text): Boolean
+ begin
+ CheckInitialization();
+ exit(IFileConnector.DirectoryExists(CurrFileAccount."Account Id", Path));
+ end;
+
+ internal procedure DeleteDirectory(Path: Text)
+ begin
+ CheckInitialization();
+ IFileConnector.DeleteDirectory(CurrFileAccount."Account Id", Path);
+ end;
+
+ internal procedure PathSeparator(): Text
+ begin
+ CheckInitialization();
+ exit(IFileConnector.PathSeparator());
+ end;
+
+ internal procedure CombinePath(Path: Text; ChildPath: Text): Text
+ begin
+ if Path = '' then
+ exit(ChildPath);
+
+ if not Path.EndsWith(PathSeparator()) then
+ Path += PathSeparator();
+
+ exit(Path + ChildPath);
+ end;
+
+ internal procedure GetParentPath(Path: Text) ParentPath: Text
+ begin
+ if (Path.TrimEnd(PathSeparator()).Contains(PathSeparator())) then
+ ParentPath := Path.TrimEnd(PathSeparator()).Substring(1, Path.LastIndexOf(PathSeparator()));
+ end;
+
+ internal procedure SelectFolderUI(Path: Text; DialogTitle: Text): Text
+ var
+ FileAccountContent: Record "File Account Content";
+ FileAccountBrowser: Page "File Account Browser";
+ begin
+ CheckInitialization();
+
+ FileAccountBrowser.SetPageCaption(DialogTitle);
+ FileAccountBrowser.SetFileAcconut(CurrFileAccount);
+ FileAccountBrowser.EnableDirectoryLookupMode(Path);
+ if FileAccountBrowser.RunModal() <> Action::LookupOK then
+ exit('');
+
+ FileAccountBrowser.GetRecord(FileAccountContent);
+ if FileAccountContent.Type <> FileAccountContent.Type::Directory then
+ exit('');
+
+ exit(CombinePath(FileAccountContent."Parent Directory", FileAccountContent.Name));
+ end;
+
+ internal procedure SelectFileUI(Path: Text; FileFilter: Text; DialogTitle: Text): Text
+ var
+ FileAccountContent: Record "File Account Content";
+ FileAccountBrowser: Page "File Account Browser";
+ begin
+ CheckInitialization();
+
+ FileAccountBrowser.SetPageCaption(DialogTitle);
+ FileAccountBrowser.SetFileAcconut(CurrFileAccount);
+ FileAccountBrowser.EnableFileLookupMode(Path, FileFilter);
+ if FileAccountBrowser.RunModal() <> Action::LookupOK then
+ exit('');
+
+ FileAccountBrowser.GetRecord(FileAccountContent);
+ if FileAccountContent.Type <> FileAccountContent.Type::File then
+ exit('');
+
+ exit(CombinePath(FileAccountContent."Parent Directory", FileAccountContent.Name));
+ end;
+
+ internal procedure SaveFileUI(Path: Text; FileExtension: Text; DialogTitle: Text): Text
+ var
+ FileAccountContent: Record "File Account Content";
+ FileAccountBrowser: Page "File Account Browser";
+ FileName, FileNameWithExtenion : Text;
+ PleaseProvideFileExtensionErr: Label 'Please provide a valid file extension.';
+ FileNameTok: Label '%1.%2', Locked = true;
+ begin
+ CheckInitialization();
+
+ if FileExtension = '' then
+ Error(PleaseProvideFileExtensionErr);
+
+ FileAccountBrowser.SetPageCaption(DialogTitle);
+ FileAccountBrowser.SetFileAcconut(CurrFileAccount);
+ FileAccountBrowser.EnableSaveFileLookupMode(Path, FileExtension);
+ if FileAccountBrowser.RunModal() <> Action::LookupOK then
+ exit('');
+
+ FileName := FileAccountBrowser.GetFileName();
+ if FileName = '' then
+ exit('');
+
+ FileNameWithExtenion := StrSubstNo(FileNameTok, FileName, FileExtension);
+ exit(CombinePath(FileAccountBrowser.GetCurrentDirectory(), FileNameWithExtenion));
+ end;
+
+ internal procedure BrowseAccount()
+ var
+ FileAccountImpl: Codeunit "File Account Impl.";
+ begin
+ CheckInitialization();
+ FileAccountImpl.BrowseAccount(CurrFileAccount);
+ end;
+
+ local procedure CheckInitialization()
+ var
+ NotInitializedErr: Label 'Please call Initalize() first.';
+ begin
+ if Initialized then
+ exit;
+
+ Error(NotInitializedErr);
+ end;
+}
\ No newline at end of file
diff --git a/src/System Application/App/File System/src/Lookup/FileAccountBrowser.Page.al b/src/System Application/App/File System/src/Lookup/FileAccountBrowser.Page.al
new file mode 100644
index 0000000000..fec745954b
--- /dev/null
+++ b/src/System Application/App/File System/src/Lookup/FileAccountBrowser.Page.al
@@ -0,0 +1,315 @@
+// ------------------------------------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License. See License.txt in the project root for license information.
+// ------------------------------------------------------------------------------------------------
+
+namespace System.FileSystem;
+
+page 70005 "File Account Browser"
+{
+ Caption = 'File Account Browser';
+ PageType = List;
+ SourceTable = "File Account Content";
+ ModifyAllowed = false;
+ InsertAllowed = false;
+ DeleteAllowed = false;
+ Extensible = false;
+
+ layout
+ {
+ area(content)
+ {
+ repeater(General)
+ {
+ field(Name; Rec.Name)
+ {
+ DrillDown = true;
+ ApplicationArea = All;
+ ToolTip = 'Specifies the value of the Name field.';
+
+ trigger OnDrillDown()
+ begin
+ if Rec.Type = Rec.Type::Directory then
+ BrowseFolder(Rec)
+ else
+ if not IsInLookupMode then
+ DownloadFile(Rec);
+ end;
+ }
+ field("Type"; Rec."Type")
+ {
+ ApplicationArea = All;
+ ToolTip = 'Specifies the value of the Type field.';
+ }
+ }
+
+ group(SaveFileNameGroup)
+ {
+ Caption = '', Locked = true;
+ ShowCaption = false;
+ Visible = ShowFileName;
+
+ field(SaveFileNameField; SaveFileName)
+ {
+ ApplicationArea = All;
+ Caption = 'Filename';
+ }
+ }
+ }
+ }
+
+ actions
+ {
+ area(Promoted)
+ {
+ actionref(UpRef; Up) { }
+ actionref(UploadRef; Upload) { }
+ actionref(CreateDirectoryRef; "Create Directory") { }
+ actionref(DeleteRef; Delete) { }
+ }
+ area(Processing)
+ {
+ action(Up)
+ {
+ Caption = 'Up';
+ ApplicationArea = All;
+ Image = MoveUp;
+ Enabled = ParentFolderExists;
+
+ trigger OnAction()
+ var
+ Path: Text;
+ begin
+ if CurrPath = '' then
+ exit;
+
+ Path := FileSystem.GetParentPath(CurrPath);
+ BrowseFolder(Path);
+ end;
+ }
+ action(Upload)
+ {
+ Caption = 'Upload';
+ ApplicationArea = All;
+ Image = Import;
+ Ellipsis = true;
+ Visible = not IsInLookupMode;
+ Enabled = not IsInLookupMode;
+
+ trigger OnAction()
+ begin
+ UploadFile();
+ BrowseFolder(CurrPath);
+ end;
+ }
+ action("Create Directory")
+ {
+ Caption = 'Create Directory';
+ ApplicationArea = All;
+ Image = Bin;
+ Ellipsis = true;
+ Visible = not IsInLookupMode;
+ Enabled = not IsInLookupMode;
+
+ trigger OnAction()
+ begin
+ CreateDirectory();
+ BrowseFolder(CurrPath);
+ end;
+ }
+ action(Delete)
+ {
+ Caption = 'Delete';
+ ApplicationArea = All;
+ Image = Delete;
+ Ellipsis = true;
+ Visible = not IsInLookupMode;
+ Enabled = not IsInLookupMode;
+
+ trigger OnAction()
+ begin
+ DeleteFileOrDirectory();
+ BrowseFolder(CurrPath);
+ end;
+ }
+ }
+ }
+
+ var
+ FileSystem: Codeunit "File System";
+ CurrPath, CurrFileFilter, SaveFileName, CurrPageCaption : Text;
+ ParentFolderExists, DoNotLoadFields, IsInLookupMode, ShowFileName : Boolean;
+
+ trigger OnOpenPage()
+ begin
+ if CurrPageCaption <> '' then
+ CurrPage.Caption(CurrPageCaption);
+ end;
+
+ internal procedure SetFileAcconut(FileAccount: Record "File Account")
+ begin
+ FileSystem.Initialize(FileAccount);
+ end;
+
+ internal procedure BrowseFileAccount(Path: Text)
+ begin
+ BrowseFolder('');
+ end;
+
+ internal procedure EnableFileLookupMode(Path: Text; FileFilter: Text)
+ begin
+ CurrFileFilter := FileFilter;
+ EnableLookupMode();
+ BrowseFolder(Path);
+ end;
+
+ internal procedure EnableDirectoryLookupMode(Path: Text)
+ begin
+ DoNotLoadFields := true;
+ EnableLookupMode();
+ BrowseFolder(Path);
+ end;
+
+ internal procedure EnableSaveFileLookupMode(Path: Text; FileExtension: Text)
+ var
+ FileFilterTok: Label '*.%1', Locked = true;
+ begin
+ ShowFileName := true;
+ CurrFileFilter := StrSubstNo(FileFilterTok, FileExtension);
+ EnableLookupMode();
+ BrowseFolder(Path);
+ end;
+
+ internal procedure GetCurrentDirectory(): Text
+ begin
+ exit(CurrPath);
+ end;
+
+ internal procedure GetFileName(): Text
+ begin
+ exit(SaveFileName);
+ end;
+
+
+ internal procedure SetPageCaption(NewCaption: Text)
+ begin
+ CurrPageCaption := NewCaption;
+ end;
+
+ local procedure StripNotsupportChrInFileName(InText: Text): Text
+ var
+ InvalidChrStringTxt: Label '"#%&*:<>?\/{|}~', Locked = true;
+ begin
+ InText := DelChr(InText, '=', InvalidChrStringTxt);
+ exit(InText);
+ end;
+
+ local procedure EnableLookupMode()
+ begin
+ IsInLookupMode := true;
+ CurrPage.LookupMode(true);
+ end;
+
+ local procedure BrowseFolder(var TempFileAccountContent: Record "File Account Content" temporary)
+ var
+ Path: Text;
+ begin
+ Path := FileSystem.CombinePath(TempFileAccountContent."Parent Directory", TempFileAccountContent.Name);
+ BrowseFolder(Path);
+ end;
+
+ local procedure BrowseFolder(Path: Text)
+ var
+ FilePaginationData: Codeunit "File Pagination Data";
+ begin
+ CurrPath := Path;
+ ParentFolderExists := Path <> '';
+ Rec.DeleteAll();
+
+ repeat
+ FileSystem.ListDirectories(Path, FilePaginationData, Rec);
+ until FilePaginationData.IsEndOfListing();
+
+ ListFiles(Path);
+ if Rec.FindFirst() then;
+ end;
+
+ local procedure DownloadFile(var TempFileAccountContent: Record "File Account Content" temporary)
+ var
+ Stream: InStream;
+ begin
+ FileSystem.GetFile(FileSystem.CombinePath(TempFileAccountContent."Parent Directory", TempFileAccountContent.Name), Stream);
+ DownloadFromStream(Stream, '', '', '', TempFileAccountContent.Name);
+ end;
+
+ local procedure UploadFile()
+ var
+ UploadDialogTxt: Label 'Upload File';
+ FromFile: Text;
+ Stream: InStream;
+ begin
+ if not UploadIntoStream(UploadDialogTxt, '', '', FromFile, Stream) then
+ exit;
+
+ FileSystem.SetFile(FileSystem.CombinePath(CurrPath, FromFile), Stream);
+ end;
+
+ local procedure CreateDirectory()
+ var
+ FolderNameInput: Page "Folder Name Input";
+ FolderName: Text;
+ begin
+ if FolderNameInput.RunModal() <> Action::OK then
+ exit;
+
+ FolderName := StripNotsupportChrInFileName(FolderNameInput.GetFolderName());
+ FileSystem.CreateDirectory(FileSystem.CombinePath(CurrPath, FolderName));
+ end;
+
+ local procedure ListFiles(var Path: Text)
+ var
+ FileAccountContent: Record "File Account Content" temporary;
+ FilePaginationData: Codeunit "File Pagination Data";
+ begin
+ if DoNotLoadFields then
+ exit;
+
+ repeat
+ FileSystem.ListFiles(Path, FilePaginationData, FileAccountContent);
+ until FilePaginationData.IsEndOfListing();
+
+ AddFiles(FileAccountContent);
+ end;
+
+ local procedure AddFiles(var FileAccountContent: Record "File Account Content" temporary)
+ begin
+ if CurrFileFilter <> '' then
+ FileAccountContent.SetFilter(Name, CurrFileFilter);
+
+ if not FileAccountContent.FindSet() then
+ exit;
+
+ repeat
+ Rec.Init();
+ Rec.TransferFields(FileAccountContent);
+ Rec.Insert();
+ until FileAccountContent.Next() = 0;
+ end;
+
+ local procedure DeleteFileOrDirectory()
+ var
+ PathToDelete: Text;
+ DeleteQst: Label 'Delete %1?', Comment = '%1 - Path to Delete';
+ begin
+ PathToDelete := FileSystem.CombinePath(Rec."Parent Directory", Rec.Name);
+ if not Confirm(DeleteQst, false, PathToDelete) then
+ exit;
+
+ case Rec.Type of
+ Rec.Type::Directory:
+ FileSystem.DeleteDirectory(PathToDelete);
+ Rec.Type::File:
+ FileSystem.DeleteFile(PathToDelete);
+ end;
+ end;
+}
diff --git a/src/System Application/App/File System/src/Lookup/FileAccountContent.Table.al b/src/System Application/App/File System/src/Lookup/FileAccountContent.Table.al
new file mode 100644
index 0000000000..f4ca1d3ead
--- /dev/null
+++ b/src/System Application/App/File System/src/Lookup/FileAccountContent.Table.al
@@ -0,0 +1,39 @@
+// ------------------------------------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License. See License.txt in the project root for license information.
+// ------------------------------------------------------------------------------------------------
+
+namespace System.FileSystem;
+
+table 70005 "File Account Content"
+{
+ Caption = 'File Account Content';
+ DataClassification = SystemMetadata;
+ TableType = Temporary;
+
+ fields
+ {
+ field(1; "Type"; Enum "File Type")
+ {
+ Caption = 'Type';
+ DataClassification = ToBeClassified;
+ }
+ field(2; Name; Text[2048])
+ {
+ Caption = 'Name';
+ DataClassification = ToBeClassified;
+ }
+ field(10; "Parent Directory"; Text[2048])
+ {
+ Caption = 'Parent Directory';
+ DataClassification = ToBeClassified;
+ }
+ }
+ keys
+ {
+ key(PK; "Type", Name)
+ {
+ Clustered = true;
+ }
+ }
+}
diff --git a/src/System Application/App/File System/src/Lookup/FilePaginationData.Codeunit.al b/src/System Application/App/File System/src/Lookup/FilePaginationData.Codeunit.al
new file mode 100644
index 0000000000..6a5dc90cfc
--- /dev/null
+++ b/src/System Application/App/File System/src/Lookup/FilePaginationData.Codeunit.al
@@ -0,0 +1,33 @@
+// ------------------------------------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License. See License.txt in the project root for license information.
+// ------------------------------------------------------------------------------------------------
+
+namespace System.FileSystem;
+
+codeunit 70006 "File Pagination Data"
+{
+ var
+ Marker: Text;
+ EndOfListing: Boolean;
+
+ procedure SetMarker(NewMarker: Text)
+ begin
+ Marker := NewMarker;
+ end;
+
+ procedure GetMarker(): Text
+ begin
+ exit(Marker);
+ end;
+
+ procedure SetEndOfListing(NewEndOfListing: Boolean)
+ begin
+ EndOfListing := NewEndOfListing;
+ end;
+
+ procedure IsEndOfListing(): Boolean
+ begin
+ exit(EndOfListing);
+ end;
+}
diff --git a/src/System Application/App/File System/src/Lookup/FileType.Enum.al b/src/System Application/App/File System/src/Lookup/FileType.Enum.al
new file mode 100644
index 0000000000..54f6ea811f
--- /dev/null
+++ b/src/System Application/App/File System/src/Lookup/FileType.Enum.al
@@ -0,0 +1,31 @@
+// ------------------------------------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License. See License.txt in the project root for license information.
+// ------------------------------------------------------------------------------------------------
+
+namespace System.FileSystem;
+
+///
+/// Indicator of what type the resource is.
+///
+enum 70002 "File Type"
+{
+ Access = Public;
+ Extensible = false;
+
+ ///
+ /// Indicates if entry is a directory.
+ ///
+ value(0; Directory)
+ {
+ Caption = 'Directory', Locked = true;
+ }
+
+ ///
+ /// Indicates if entry is a file type.
+ ///
+ value(1; File)
+ {
+ Caption = 'File', Locked = true;
+ }
+}
\ No newline at end of file
diff --git a/src/System Application/App/File System/src/Lookup/FolderNameInput.Page.al b/src/System Application/App/File System/src/Lookup/FolderNameInput.Page.al
new file mode 100644
index 0000000000..23239dcce3
--- /dev/null
+++ b/src/System Application/App/File System/src/Lookup/FolderNameInput.Page.al
@@ -0,0 +1,33 @@
+// ------------------------------------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License. See License.txt in the project root for license information.
+// ------------------------------------------------------------------------------------------------
+
+namespace System.FileSystem;
+
+page 70006 "Folder Name Input"
+{
+ ApplicationArea = All;
+ Caption = 'Create Folder...';
+ PageType = StandardDialog;
+ Extensible = false;
+
+ layout
+ {
+ area(content)
+ {
+ field(FolderNameField; FolderName)
+ {
+ Caption = 'Folder Name';
+ }
+ }
+ }
+
+ var
+ FolderName: Text;
+
+ internal procedure GetFolderName(): Text
+ begin
+ exit(FolderName);
+ end;
+}
diff --git a/src/System Application/App/File System/src/Scenario/FileAccountScenario.Table.al b/src/System Application/App/File System/src/Scenario/FileAccountScenario.Table.al
new file mode 100644
index 0000000000..649a7b951e
--- /dev/null
+++ b/src/System Application/App/File System/src/Scenario/FileAccountScenario.Table.al
@@ -0,0 +1,74 @@
+// ------------------------------------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License. See License.txt in the project root for license information.
+// ------------------------------------------------------------------------------------------------
+
+namespace System.FileSystem;
+
+///
+/// Temporary table used to display the tree sctructure in "File Scenario Setup".
+///
+table 70003 "File Account Scenario"
+{
+ Access = Internal;
+ InherentPermissions = X;
+ InherentEntitlements = X;
+ TableType = Temporary;
+
+ fields
+ {
+ field(1; Scenario; Integer)
+ {
+ DataClassification = SystemMetadata;
+ }
+
+ field(2; Connector; Enum "File System Connector")
+ {
+ DataClassification = SystemMetadata;
+ }
+
+ field(3; "Account Id"; Guid)
+ {
+ DataClassification = SystemMetadata;
+ }
+
+ field(4; "Display Name"; Text[2048])
+ {
+ DataClassification = SystemMetadata;
+ }
+
+ field(5; Default; Boolean)
+ {
+ DataClassification = SystemMetadata;
+ }
+
+ field(6; EntryType; Option)
+ {
+ DataClassification = SystemMetadata;
+ OptionMembers = Account,Scenario;
+ }
+
+ field(7; Position; Integer)
+ {
+ DataClassification = SystemMetadata;
+ }
+ }
+
+ keys
+ {
+ key(PK; Scenario, "Account Id", Connector)
+ {
+ Clustered = true;
+ }
+
+ key(Position; Position)
+ {
+
+ }
+
+ key(Name; "Display Name")
+ {
+ Description = 'Used for sorting by Dispay Name';
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/System Application/App/File System/src/Scenario/FileScenario.Codeunit.al b/src/System Application/App/File System/src/Scenario/FileScenario.Codeunit.al
new file mode 100644
index 0000000000..46a191fb45
--- /dev/null
+++ b/src/System Application/App/File System/src/Scenario/FileScenario.Codeunit.al
@@ -0,0 +1,76 @@
+// ------------------------------------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License. See License.txt in the project root for license information.
+// ------------------------------------------------------------------------------------------------
+
+namespace System.FileSystem;
+
+///
+/// Provides functionality to work with file scenarios.
+///
+codeunit 70002 "File Scenario"
+{
+ ///
+ /// Gets the default file account.
+ ///
+ /// Out parameter holding information about the default file account.
+ /// True if an account for the the default scenario was found; otherwise - false.
+ procedure GetDefaultFileAccount(var FileAccount: Record "File Account"): Boolean
+ begin
+ exit(FileScenarioImpl.GetFileAccount(Enum::"File Scenario"::Default, FileAccount));
+ end;
+
+ ///
+ /// Gets the file account used by the given file scenario.
+ /// If the no account is defined for the provided scenario, the default account (if defined) will be returned.
+ ///
+ /// The scenario to look for.
+ /// Out parameter holding information about the file account.
+ /// True if an account for the specified scenario was found; otherwise - false.
+ procedure GetFileAccount(Scenario: Enum "File Scenario"; var FileAccount: Record "File Account"): Boolean
+ begin
+ exit(FileScenarioImpl.GetFileAccount(Scenario, FileAccount));
+ end;
+
+ ///
+ /// Sets a default file account.
+ ///
+ /// The file account to use.
+ procedure SetDefaultFileAccount(FileAccount: Record "File Account")
+ begin
+ FileScenarioImpl.SetFileAccount(Enum::"File Scenario"::Default, FileAccount);
+ end;
+
+ ///
+ /// Sets an file account to be used by the given file scenario.
+ ///
+ /// The scenario for which to set an file account.
+ /// The file account to use.
+ procedure SetFileAccount(Scenario: Enum "File Scenario"; FileAccount: Record "File Account")
+ begin
+ FileScenarioImpl.SetFileAccount(Scenario, FileAccount);
+ end;
+
+ ///
+ /// Unassign an file scenario. The scenario will then use the default file account.
+ ///
+ /// The scenario to unassign.
+ procedure UnassignScenario(Scenario: Enum "File Scenario")
+ begin
+ FileScenarioImpl.UnassignScenario(Scenario);
+ end;
+
+ ///
+ /// Event for changing whether an file scenario should be added to the list of assignable scenarios.
+ /// If the scenario has already been assigned or is the default scenario, this event won't be published.
+ ///
+ /// The scenario that is going to be added to the list of assignable scenarios.
+ /// The return for whether this scenario should be listed in the assignable scenarios list.
+ [IntegrationEvent(false, false, true)]
+ internal procedure OnBeforeInsertAvailableFileScenario(Scenario: Enum "File Scenario"; var IsAvailable: Boolean)
+ begin
+ end;
+
+ var
+ FileScenarioImpl: Codeunit "File Scenario Impl.";
+}
\ No newline at end of file
diff --git a/src/System Application/App/File System/src/Scenario/FileScenario.Enum.al b/src/System Application/App/File System/src/Scenario/FileScenario.Enum.al
new file mode 100644
index 0000000000..7a31b1238c
--- /dev/null
+++ b/src/System Application/App/File System/src/Scenario/FileScenario.Enum.al
@@ -0,0 +1,24 @@
+// ------------------------------------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License. See License.txt in the project root for license information.
+// ------------------------------------------------------------------------------------------------
+
+namespace System.FileSystem;
+
+///
+/// File scenarios.
+/// Used to decouple file accounts from sending files.
+///
+enum 70001 "File Scenario"
+{
+ Extensible = true;
+
+ ///
+ /// The default file scenario.
+ /// Used in the cases where no other scenario is defined.
+ ///
+ value(0; Default)
+ {
+ Caption = 'Default';
+ }
+}
\ No newline at end of file
diff --git a/src/System Application/App/File System/src/Scenario/FileScenario.Table.al b/src/System Application/App/File System/src/Scenario/FileScenario.Table.al
new file mode 100644
index 0000000000..2258a9c28f
--- /dev/null
+++ b/src/System Application/App/File System/src/Scenario/FileScenario.Table.al
@@ -0,0 +1,42 @@
+// ------------------------------------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License. See License.txt in the project root for license information.
+// ------------------------------------------------------------------------------------------------
+
+namespace System.FileSystem;
+
+///
+/// Holds the mapping between file account and scenarios.
+/// One scenarios is mapped to one file account.
+/// One file account can be used for multiple scenarios.
+///
+table 70004 "File Scenario"
+{
+ Access = Internal;
+
+ fields
+ {
+ field(1; Scenario; Enum "File Scenario")
+ {
+ DataClassification = SystemMetadata;
+ }
+
+ field(2; Connector; Enum "File System Connector")
+ {
+ DataClassification = SystemMetadata;
+ }
+
+ field(3; "Account Id"; Guid)
+ {
+ DataClassification = SystemMetadata;
+ }
+ }
+
+ keys
+ {
+ key(PK; Scenario)
+ {
+ Clustered = true;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/System Application/App/File System/src/Scenario/FileScenarioImpl.Codeunit.al b/src/System Application/App/File System/src/Scenario/FileScenarioImpl.Codeunit.al
new file mode 100644
index 0000000000..6c0922fdfc
--- /dev/null
+++ b/src/System Application/App/File System/src/Scenario/FileScenarioImpl.Codeunit.al
@@ -0,0 +1,329 @@
+// ------------------------------------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License. See License.txt in the project root for license information.
+// ------------------------------------------------------------------------------------------------
+
+namespace System.FileSystem;
+
+using System;
+
+codeunit 70003 "File Scenario Impl."
+{
+ Access = Internal;
+ InherentPermissions = X;
+ InherentEntitlements = X;
+ Permissions = TableData "File Scenario" = rimd;
+
+ procedure GetFileAccount(Scenario: Enum "File Scenario"; var FileAccount: Record "File Account"): Boolean
+ var
+ FileScenario: Record "File Scenario";
+ AllFileAccounts: Record "File Account";
+ FileAccounts: Codeunit "File Account";
+ begin
+ FileAccounts.GetAllAccounts(AllFileAccounts);
+
+ // Find the account for the provided scenario
+ if FileScenario.Get(Scenario) then
+ if AllFileAccounts.Get(FileScenario."Account Id", FileScenario.Connector) then begin
+ FileAccount := AllFileAccounts;
+ exit(true);
+ end;
+
+ // Fallback to the default account if the scenario isn't mapped or the mapped account doesn't exist
+ if FileScenario.Get(Enum::"File Scenario"::Default) then
+ if AllFileAccounts.Get(FileScenario."Account Id", FileScenario.Connector) then begin
+ FileAccount := AllFileAccounts;
+ exit(true);
+ end;
+
+ exit(false);
+ end;
+
+ procedure SetFileAccount(Scenario: Enum "File Scenario"; FileAccount: Record "File Account")
+ var
+ FileScenario: Record "File Scenario";
+ begin
+ if not FileScenario.Get(Scenario) then begin
+ FileScenario.Scenario := Scenario;
+ FileScenario.Insert();
+ end;
+
+ FileScenario."Account Id" := FileAccount."Account Id";
+ FileScenario.Connector := FileAccount.Connector;
+
+ FileScenario.Modify();
+ end;
+
+ procedure UnassignScenario(Scenario: Enum "File Scenario")
+ var
+ FileScenario: Record "File Scenario";
+ begin
+ if FileScenario.Get(Scenario) then
+ FileScenario.Delete();
+ end;
+
+ ///
+ /// Get a list of entries, representing a tree structure with file accounts and the scenarios, assigned to each accout.
+ ///
+ ///
+ /// Account sales@cronus.com has scenarios "Sales Quote" and "Sales Credit Memo" assigned.
+ /// Account purchase@cronus.com has scenarios "Purchase Quote" and "Purchase Invoice" assigned.
+ /// The result of calling the function will be:
+ /// sales@cronus.com, "Sales Quote", "Sales Credit Memo", purchase@cronus.com, "Purchase Quote", "Purchase Invoice"
+ ///
+ /// A flatten tree structure representing the all the file accounts and the scenarios assigned to them.
+ procedure GetScenariosByFileAccount(var Result: Record "File Account Scenario")
+ var
+ FileAccounts: Record "File Account";
+ FileAccountScenarios: Record "File Account Scenario";
+ DefaultAccount: Record "File Account";
+ FileAccount: Codeunit "File Account";
+ DisplayName: Text[2048];
+ Position: Integer;
+ Default: Boolean;
+ begin
+ Result.Reset();
+ Result.DeleteAll();
+
+ FileAccount.GetAllAccounts(FileAccounts);
+
+ if not FileAccounts.FindSet() then
+ exit; // No accounts, nothing to do
+
+ // The position is set in order to be able to properly sort the entries (by order of insertion)
+ Position := 1;
+ GetDefaultAccount(DefaultAccount);
+
+ repeat
+ Default := (FileAccounts."Account Id" = DefaultAccount."Account Id") and (FileAccounts.Connector = DefaultAccount.Connector);
+ DisplayName := FileAccounts.Name;
+
+ // Add entry for the file account. Scenario is -1, because it isn't needed when displaying the file account.
+ AddEntry(Result, Result.EntryType::Account, -1, FileAccounts."Account Id", FileAccounts.Connector, DisplayName, Default, Position);
+
+ // Get the file scenarios assigned to the current file account, sorted by "Display Name"
+ GetFileScenariosForAccount(FileAccounts, FileAccountScenarios);
+
+ if FileAccountScenarios.FindSet() then
+ repeat
+ // Add entry for every scenario that is assigned to the current file account
+ AddEntry(Result, FileAccountScenarios.EntryType::Scenario, FileAccountScenarios.Scenario, FileAccountScenarios."Account Id", FileAccountScenarios.Connector, FileAccountScenarios."Display Name", false, Position);
+ until FileAccountScenarios.Next() = 0;
+ until FileAccounts.Next() = 0;
+
+ // Order by position to show accurate results
+ Result.SetCurrentKey(Position);
+ end;
+
+ local procedure GetFileScenariosForAccount(FileAccount: Record "File Account"; var FileAccountScenarios: Record "File Account Scenario")
+ var
+ FileScenarios: Record "File Scenario";
+ ValidFileScenarios: DotNet Hashtable;
+ IsScenarioValid: Boolean;
+ Scenario: Integer;
+ begin
+ FileAccountScenarios.Reset();
+ FileAccountScenarios.DeleteAll();
+
+ // Get all file scenarios assigned to the file account
+ FileScenarios.SetRange("Account Id", FileAccount."Account Id");
+ FileScenarios.SetRange(Connector, FileAccount.Connector);
+
+ if not FileScenarios.FindSet() then
+ exit;
+
+ // Find all valid scenarios. Invalid scenario may occur if the extension that added them was removed.
+ ValidFileScenarios := ValidFileScenarios.Hashtable();
+ foreach Scenario in Enum::"File Scenario".Ordinals() do
+ ValidFileScenarios.Add(Scenario, Scenario);
+
+ // Convert File Scenario-s to File Account Scenario-s so they can be sorted by "Display Name"
+ repeat
+ IsScenarioValid := ValidFileScenarios.Contains(FileScenarios.Scenario.AsInteger());
+
+ // Add entry for every scenario that exists and uses the file account. Skip the default scenario.
+ if (FileScenarios.Scenario <> Enum::"File Scenario"::Default) and IsScenarioValid then begin
+ FileAccountScenarios.Scenario := FileScenarios.Scenario.AsInteger();
+ FileAccountScenarios."Account Id" := FileScenarios."Account Id";
+ FileAccountScenarios.Connector := FileScenarios.Connector;
+ FileAccountScenarios."Display Name" := Format(FileScenarios.Scenario);
+
+ FileAccountScenarios.Insert();
+ end;
+ until FileScenarios.Next() = 0;
+
+ FileAccountScenarios.SetCurrentKey("Display Name"); // sort scenarios by "Display Name"
+ end;
+
+ local procedure AddEntry(var Result: Record "File Account Scenario"; EntryType: Option; Scenario: Integer; AccountId: Guid; Connector: Enum "File System Connector"; DisplayName: Text[2048]; Default: Boolean; var Position: Integer)
+ begin
+ // Add entry to the result while maintaining the position so that the tree represents the data correctly
+ Result.EntryType := EntryType;
+ Result.Scenario := Scenario;
+ Result."Account Id" := AccountId;
+ Result.Connector := Connector;
+ Result."Display Name" := DisplayName;
+ Result.Default := Default;
+ Result.Position := Position;
+
+ Result.Insert();
+
+ Position := Position + 1;
+ end;
+
+ procedure AddScenarios(FileAccount: Record "File Account Scenario"): Boolean
+ var
+ FileScenario: Record "File Scenario";
+ SelectedScenarios: Record "File Account Scenario";
+ ScenariosForAccount: Page "File Scenarios For Account";
+ begin
+ FileAccountImpl.CheckPermissions();
+
+ if FileAccount.EntryType <> FileAccount.EntryType::Account then // wrong entry, the entry should be of type "Account"
+ exit;
+
+ ScenariosForAccount.Caption := StrSubstNo(ScenariosForAccountCaptionTxt, FileAccount."Display Name");
+ ScenariosForAccount.LookupMode(true);
+ ScenariosForAccount.SetRecord(FileAccount);
+
+ if ScenariosForAccount.RunModal() <> Action::LookupOK then
+ exit(false);
+
+ ScenariosForAccount.GetSelectedScenarios(SelectedScenarios);
+
+ if not SelectedScenarios.FindSet() then
+ exit(false);
+
+ repeat
+ if not FileScenario.Get(SelectedScenarios.Scenario) then begin
+ FileScenario."Account Id" := FileAccount."Account Id";
+ FileScenario.Connector := FileAccount.Connector;
+ FileScenario.Scenario := Enum::"File Scenario".FromInteger(SelectedScenarios.Scenario);
+
+ FileScenario.Insert();
+ end else begin
+ FileScenario."Account Id" := FileAccount."Account Id";
+ FileScenario.Connector := FileAccount.Connector;
+
+ FileScenario.Modify();
+ end;
+ until SelectedScenarios.Next() = 0;
+
+ exit(true);
+ end;
+
+ procedure GetAvailableScenariosForAccount(FileAccount: Record "File Account Scenario"; var FileScenarios: Record "File Account Scenario")
+ var
+ Scenario: Record "File Scenario";
+ FileScenario: Codeunit "File Scenario";
+ CurrentScenario, i : Integer;
+ IsAvailable: Boolean;
+ begin
+ FileScenarios.Reset();
+ FileScenarios.DeleteAll();
+ i := 1;
+
+ foreach CurrentScenario in Enum::"File Scenario".Ordinals() do begin
+ Clear(Scenario);
+ Scenario.SetRange("Account Id", FileAccount."Account Id");
+ Scenario.SetRange(Connector, FileAccount.Connector);
+ Scenario.SetRange(Scenario, CurrentScenario);
+
+ // If the scenario isn't already connected to the file account, then it's available. Natually, we skip the default scenario
+ IsAvailable := Scenario.IsEmpty() and (not (CurrentScenario = Enum::"File Scenario"::Default.AsInteger()));
+
+ // If the scenario is available, allow partner to determine if it should be shown
+ if IsAvailable then
+ FileScenario.OnBeforeInsertAvailableFileScenario(Enum::"File Scenario".FromInteger(CurrentScenario), IsAvailable);
+
+ if IsAvailable then begin
+ FileScenarios."Account Id" := FileAccount."Account Id";
+ FileScenarios.Connector := FileAccount.Connector;
+ FileScenarios.Scenario := CurrentScenario;
+ FileScenarios."Display Name" := Format(Enum::"File Scenario".FromInteger(Enum::"File Scenario".Ordinals().Get(i)));
+
+ FileScenarios.Insert();
+ end;
+
+ i := i + 1;
+ end;
+ end;
+
+ procedure ChangeAccount(var FileScenario: Record "File Account Scenario"): Boolean
+ var
+ SelectedAccount: Record "File Account";
+ Scenario: Record "File Scenario";
+ FileAccount: Codeunit "File Account";
+ AccountsPage: Page "File Accounts";
+ begin
+ FileAccountImpl.CheckPermissions();
+
+ if not FileScenario.FindSet() then
+ exit(false);
+
+ FileAccount.GetAllAccounts(false, SelectedAccount);
+ if SelectedAccount.Get(FileScenario."Account Id", FileScenario.Connector) then;
+
+ AccountsPage.EnableLookupMode();
+ AccountsPage.SetRecord(SelectedAccount);
+ AccountsPage.Caption := ChangeFileAccountForScenarioTxt;
+
+ if AccountsPage.RunModal() <> Action::LookupOK then
+ exit(false);
+
+ AccountsPage.GetAccount(SelectedAccount);
+
+ if IsNullGuid(SelectedAccount."Account Id") then // defensive check, no account was selected
+ exit;
+
+ repeat
+ if Scenario.Get(FileScenario.Scenario) then begin
+ Scenario."Account Id" := SelectedAccount."Account Id";
+ Scenario.Connector := SelectedAccount.Connector;
+
+ Scenario.Modify();
+ end;
+ until FileScenario.Next() = 0;
+
+ exit(true);
+ end;
+
+ procedure DeleteScenario(var FileScenario: Record "File Account Scenario"): Boolean
+ var
+ Scenario: Record "File Scenario";
+ begin
+ FileAccountImpl.CheckPermissions();
+
+ if not FileScenario.FindSet() then
+ exit(false);
+
+ repeat
+ if FileScenario.EntryType = FileScenario.EntryType::Scenario then begin
+ Scenario.SetRange(Scenario, FileScenario.Scenario);
+ Scenario.SetRange("Account Id", FileScenario."Account Id");
+ Scenario.SetRange(Connector, FileScenario.Connector);
+
+ Scenario.DeleteAll();
+ end;
+ until FileScenario.Next() = 0;
+
+ exit(true);
+ end;
+
+ local procedure GetDefaultAccount(var FileAccount: Record "File Account")
+ var
+ Scenario: Record "File Scenario";
+ begin
+ if not Scenario.Get(Enum::"File Scenario"::Default) then
+ exit;
+
+ FileAccount."Account Id" := Scenario."Account Id";
+ FileAccount.Connector := Scenario.Connector;
+ end;
+
+ var
+ FileAccountImpl: Codeunit "File Account Impl.";
+ AccountDisplayLbl: Label '%1 (%2)', Locked = true;
+ ChangeFileAccountForScenarioTxt: Label 'Change file account used for the selected scenarios';
+ ScenariosForAccountCaptionTxt: Label 'Assign scenarios to account %1', Comment = '%1 = the name of the e-file account';
+}
\ No newline at end of file
diff --git a/src/System Application/App/File System/src/Scenario/FileScenarioSetup.Page.al b/src/System Application/App/File System/src/Scenario/FileScenarioSetup.Page.al
new file mode 100644
index 0000000000..2d6c1c1396
--- /dev/null
+++ b/src/System Application/App/File System/src/Scenario/FileScenarioSetup.Page.al
@@ -0,0 +1,198 @@
+// ------------------------------------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License. See License.txt in the project root for license information.
+// ------------------------------------------------------------------------------------------------
+
+namespace System.FileSystem;
+
+using System.Telemetry;
+
+///
+/// Page is used to display file scenarios usage by file accounts.
+///
+page 70002 "File Scenario Setup"
+{
+ Caption = 'File Scenario Assignment';
+ PageType = List;
+ UsageCategory = Administration;
+ ApplicationArea = All;
+ Extensible = false;
+ Editable = false;
+ DeleteAllowed = false;
+ InsertAllowed = false;
+ ModifyAllowed = false;
+ SourceTable = "File Account Scenario";
+ InstructionalText = 'Assign file scenarios';
+
+ layout
+ {
+ area(Content)
+ {
+ repeater(ScenariosByFile)
+ {
+ IndentationColumn = Indentation;
+ IndentationControls = Name;
+ ShowAsTree = true;
+
+ field(Name; Rec."Display Name")
+ {
+ ApplicationArea = All;
+ Caption = 'Scenarios by file accounts';
+ ToolTip = 'Specifies the scenarios that are using the file account.';
+ Editable = false;
+ StyleExpr = Style;
+ }
+
+ field(Default; DefaultTxt)
+ {
+ ApplicationArea = All;
+ Caption = 'Default';
+ ToolTip = 'Specifies whether this is the default account to use for scenarios when no other account is specified.';
+ StyleExpr = Style;
+ }
+ }
+ }
+ }
+
+ actions
+ {
+ area(Processing)
+ {
+ group(Account)
+ {
+ action(AddScenario)
+ {
+ Visible = (TypeOfEntry = TypeOfEntry::Account) and CanUserManageFileSetup;
+
+ ApplicationArea = All;
+ Caption = 'Assign scenarios';
+ ToolTip = 'Assign file scenarios for the selected file account. When assigned, everyone will use the account for the scenario. For example, if you assign the Sales Order scenario, everyone will use the account to send sales orders.';
+ Image = NewDocument;
+ Promoted = true;
+ PromotedOnly = true;
+ PromotedCategory = Process;
+ PromotedIsBig = true;
+ Scope = Repeater;
+
+ trigger OnAction()
+ begin
+ SelectedFileAccountScenario := Rec;
+ FileScenarioImpl.AddScenarios(Rec);
+
+ FileScenarioImpl.GetScenariosByFileAccount(Rec);
+ SetSelectedRecord();
+ end;
+ }
+ }
+
+ group(Scenario)
+ {
+ action(ChangeAccount)
+ {
+ Visible = (TypeOfEntry = TypeOfEntry::Scenario) and CanUserManageFileSetup;
+
+ ApplicationArea = All;
+ Caption = 'Reassign';
+ ToolTip = 'Reassign the selected scenarios to another file account.';
+ Image = Change;
+ Promoted = true;
+ PromotedOnly = true;
+ PromotedCategory = Process;
+ PromotedIsBig = true;
+ Scope = Repeater;
+
+ trigger OnAction()
+ begin
+ CurrPage.SetSelectionFilter(Rec);
+ SelectedFileAccountScenario := Rec;
+
+ FileScenarioImpl.ChangeAccount(Rec);
+ FileScenarioImpl.GetScenariosByFileAccount(Rec); // refresh the data on the page
+ SetSelectedRecord();
+ end;
+ }
+
+ action(Unassign)
+ {
+ Visible = (TypeOfEntry = TypeOfEntry::Scenario) and CanUserManageFileSetup;
+
+ ApplicationArea = All;
+ Caption = 'Unassign';
+ ToolTip = 'Unassign the selected scenarios. Afterward, the default file account will be used to send files for the scenarios.';
+ Image = Delete;
+ Promoted = true;
+ PromotedOnly = true;
+ PromotedCategory = Process;
+ PromotedIsBig = true;
+ Scope = Repeater;
+
+ trigger OnAction()
+ begin
+ CurrPage.SetSelectionFilter(Rec);
+ SelectedFileAccountScenario := Rec;
+
+ FileScenarioImpl.DeleteScenario(Rec);
+ FileScenarioImpl.GetScenariosByFileAccount(Rec); // refresh the data on the page
+ SetSelectedRecord();
+ end;
+ }
+ }
+ }
+ }
+
+ trigger OnOpenPage()
+ var
+ FeatureTelemetry: Codeunit "Feature Telemetry";
+ begin
+ FeatureTelemetry.LogUptake('0000CTN', 'File Access', Enum::"Feature Uptake Status"::Discovered);
+ CanUserManageFileSetup := FileAccountImpl.IsUserFileAdmin();
+ FileScenarioImpl.GetScenariosByFileAccount(Rec);
+
+ // Set selection
+ if not Rec.Get(-1, FileAccountId, FileConnector) then
+ if Rec.FindFirst() then;
+ end;
+
+ trigger OnAfterGetRecord()
+ begin
+ DefaultTxt := '';
+
+ TypeOfEntry := Rec.EntryType;
+
+ if TypeOfEntry = TypeOfEntry::Account then begin
+ Indentation := 0;
+ Style := 'Strong';
+ if Rec.Default then
+ DefaultTxt := '✓'
+ end;
+
+ if TypeOfEntry = TypeOfEntry::Scenario then begin
+ Indentation := 1;
+ Style := 'Standard';
+ end;
+ end;
+
+ // Used to set the focus on an file account
+ internal procedure SetFileAccountId(AccountId: Guid; Connector: Enum "File System Connector")
+ begin
+ FileAccountId := AccountId;
+ FileConnector := Connector;
+ end;
+
+ local procedure SetSelectedRecord()
+ begin
+ if not Rec.Get(SelectedFileAccountScenario.Scenario, SelectedFileAccountScenario."Account Id", SelectedFileAccountScenario.Connector) then
+ Rec.FindFirst();
+ end;
+
+ var
+ SelectedFileAccountScenario: Record "File Account Scenario";
+ FileScenarioImpl: Codeunit "File Scenario Impl.";
+ FileAccountImpl: Codeunit "File Account Impl.";
+ FileAccountId: Guid;
+ FileConnector: Enum "File System Connector";
+ Style, DefaultTxt : Text;
+ TypeOfEntry: Option Account,Scenario;
+ Indentation: Integer;
+ CanUserManageFileSetup: Boolean;
+}
\ No newline at end of file
diff --git a/src/System Application/App/File System/src/Scenario/FileScenariosFactBox.Page.al b/src/System Application/App/File System/src/Scenario/FileScenariosFactBox.Page.al
new file mode 100644
index 0000000000..df5bd47cc4
--- /dev/null
+++ b/src/System Application/App/File System/src/Scenario/FileScenariosFactBox.Page.al
@@ -0,0 +1,40 @@
+// ------------------------------------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License. See License.txt in the project root for license information.
+// ------------------------------------------------------------------------------------------------
+
+namespace System.FileSystem;
+
+///
+/// Lists of all scenarios assigned to an account.
+///
+page 70003 "File Scenarios FactBox"
+{
+ PageType = ListPart;
+ Extensible = false;
+ SourceTable = "File Scenario";
+ InsertAllowed = false;
+ ModifyAllowed = false;
+ DeleteAllowed = false;
+ Editable = false;
+ ShowFilter = false;
+ LinksAllowed = false;
+ Permissions = tabledata "File Scenario" = r;
+
+ layout
+ {
+ area(Content)
+ {
+ repeater(ScenariosByFile)
+ {
+ field(Name; Format(Rec.Scenario))
+ {
+ ApplicationArea = All;
+ ToolTip = 'The file scenario.';
+ Caption = 'File scenario';
+ Editable = false;
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/System Application/App/File System/src/Scenario/FileScenariosForAccount.Page.al b/src/System Application/App/File System/src/Scenario/FileScenariosForAccount.Page.al
new file mode 100644
index 0000000000..ee44822462
--- /dev/null
+++ b/src/System Application/App/File System/src/Scenario/FileScenariosForAccount.Page.al
@@ -0,0 +1,65 @@
+// ------------------------------------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License. See License.txt in the project root for license information.
+// ------------------------------------------------------------------------------------------------
+
+namespace System.FileSystem;
+
+///
+/// Displays the scenarios that could be linked to a provided file account.
+///
+page 70004 "File Scenarios for Account"
+{
+ PageType = List;
+ Extensible = false;
+ SourceTable = "File Account Scenario";
+ InsertAllowed = false;
+ ModifyAllowed = false;
+ DeleteAllowed = false;
+ Editable = false;
+ ShowFilter = false;
+ LinksAllowed = false;
+
+ layout
+ {
+ area(Content)
+ {
+ repeater(ScenariosByFile)
+ {
+ field(Name; Rec."Display Name")
+ {
+ ApplicationArea = All;
+ ToolTip = 'The file scenario.';
+ Caption = 'File scenario';
+ Editable = false;
+ }
+ }
+ }
+ }
+
+ internal procedure GetSelectedScenarios(var ResultFileAccountScenario: Record "File Account Scenario")
+ begin
+ ResultFileAccountScenario.Reset();
+ ResultFileAccountScenario.DeleteAll();
+
+ CurrPage.SetSelectionFilter(Rec);
+
+ if not Rec.FindSet() then
+ exit;
+
+ repeat
+ ResultFileAccountScenario.Copy(Rec);
+ ResultFileAccountScenario.Insert();
+ until Rec.Next() = 0;
+ end;
+
+ trigger OnOpenPage()
+ begin
+ FileScenarioImpl.GetAvailableScenariosForAccount(Rec, Rec);
+ Rec.SetCurrentKey("Display Name");
+ if Rec.FindFirst() then; // set the selection to the first record
+ end;
+
+ var
+ FileScenarioImpl: Codeunit "File Scenario Impl.";
+}
\ No newline at end of file
diff --git a/src/System Application/Test Library/File System/Permissions/FileSystemAdmin.PermissionSet.al b/src/System Application/Test Library/File System/Permissions/FileSystemAdmin.PermissionSet.al
new file mode 100644
index 0000000000..8888e89d7b
--- /dev/null
+++ b/src/System Application/Test Library/File System/Permissions/FileSystemAdmin.PermissionSet.al
@@ -0,0 +1,19 @@
+// ------------------------------------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License. See License.txt in the project root for license information.
+// ------------------------------------------------------------------------------------------------
+
+namespace System.TestLibraries.FileSystem;
+
+using System.FileSystem;
+
+permissionset 80200 "File System Admin"
+{
+ Assignable = true;
+ IncludedPermissionSets = "File System - Admin";
+
+ // Include Test Tables
+ Permissions =
+ tabledata "Test File Connector Setup" = RIMD,
+ tabledata "Test File Account" = RIMD;
+}
\ No newline at end of file
diff --git a/src/System Application/Test Library/File System/Permissions/FileSystemEdit.PermissionSet.al b/src/System Application/Test Library/File System/Permissions/FileSystemEdit.PermissionSet.al
new file mode 100644
index 0000000000..eaea59bcff
--- /dev/null
+++ b/src/System Application/Test Library/File System/Permissions/FileSystemEdit.PermissionSet.al
@@ -0,0 +1,21 @@
+// ------------------------------------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License. See License.txt in the project root for license information.
+// ------------------------------------------------------------------------------------------------
+
+namespace System.TestLibraries.FileSystem;
+
+using System.FileSystem;
+using System.Environment;
+
+permissionset 80201 "File System Edit"
+{
+ Assignable = true;
+ IncludedPermissionSets = "File System - Edit";
+
+ // Include Test Tables
+ Permissions =
+ tabledata "Test File Connector Setup" = RIMD,
+ tabledata "Test File Account" = RIMD, // Needed for the Record to get passed in Library Assert
+ tabledata "Scheduled Task" = rd; // Needed for enqueue tests
+}
\ No newline at end of file
diff --git a/src/System Application/Test Library/File System/app.json b/src/System Application/Test Library/File System/app.json
new file mode 100644
index 0000000000..0c98188146
--- /dev/null
+++ b/src/System Application/Test Library/File System/app.json
@@ -0,0 +1,39 @@
+{
+ "id": "f188754b-3ffb-443a-9507-f5fbdae3af2c",
+ "name": "File System Test Library",
+ "publisher": "Microsoft",
+ "brief": "Test library for the Email module",
+ "description": "Test library for the Email module",
+ "version": "25.0.0.0",
+ "privacyStatement": "https://go.microsoft.com/fwlink/?linkid=724009",
+ "EULA": "https://go.microsoft.com/fwlink/?linkid=2009120",
+ "help": "https://go.microsoft.com/fwlink/?linkid=2103698",
+ "url": "https://go.microsoft.com/fwlink/?linkid=724011",
+ "logo": "",
+ "dependencies": [
+ {
+ "id": "c9c54414-80c3-4cc9-98c6-589158882774",
+ "name": "File System",
+ "publisher": "Microsoft",
+ "version": "25.0.0.0"
+ },
+ {
+ "id": "e7320ebb-08b3-4406-b1ec-b4927d3e280b",
+ "name": "Any",
+ "publisher": "Microsoft",
+ "version": "25.0.0.0"
+ }
+ ],
+ "screenshots": [
+
+ ],
+ "platform": "25.0.0.0",
+ "idRanges": [
+ {
+ "from": 80200,
+ "to": 800299
+ }
+ ],
+ "contextSensitiveHelpUrl": "https://go.microsoft.com/fwlink/?linkid=2134520",
+ "target": "OnPrem"
+}
\ No newline at end of file
diff --git a/src/System Application/Test Library/File System/src/ConnectorMock.Codeunit.al b/src/System Application/Test Library/File System/src/ConnectorMock.Codeunit.al
new file mode 100644
index 0000000000..e7f175e5da
--- /dev/null
+++ b/src/System Application/Test Library/File System/src/ConnectorMock.Codeunit.al
@@ -0,0 +1,136 @@
+// ------------------------------------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License. See License.txt in the project root for license information.
+// ------------------------------------------------------------------------------------------------
+
+namespace System.TestLibraries.FileSystem;
+
+using System.FileSystem;
+using System.TestLibraries.Utilities;
+
+codeunit 80200 "Connector Mock"
+{
+ var
+ Any: Codeunit Any;
+
+ procedure Initialize()
+ var
+ TestFileConnectorSetup: Record "Test File Connector Setup";
+ TestFileAccount: Record "Test File Account";
+ begin
+ TestFileConnectorSetup.DeleteAll();
+ TestFileConnectorSetup.Init();
+ TestFileConnectorSetup.Id := Any.GuidValue();
+ TestFileConnectorSetup."Fail On Send" := false;
+ TestFileConnectorSetup."Fail On Register Account" := false;
+ TestFileConnectorSetup."Unsuccessful Register" := false;
+ TestFileConnectorSetup.Insert();
+
+ TestFileAccount.DeleteAll();
+ end;
+
+ procedure GetAccounts(var FileAccount: Record "File Account")
+ var
+ TestFileAccount: Record "Test File Account";
+ begin
+ if TestFileAccount.FindSet() then
+ repeat
+ FileAccount.Init();
+ FileAccount."Account Id" := TestFileAccount.Id;
+ FileAccount.Name := TestFileAccount.Name;
+ FileAccount.Insert();
+ until TestFileAccount.Next() = 0;
+ end;
+
+ procedure AddAccount(var FileAccount: Record "File Account")
+ var
+ TestFileAccount: Record "Test File Account";
+ begin
+ TestFileAccount.Id := Any.GuidValue();
+ TestFileAccount.Name := CopyStr(Any.AlphanumericText(250), 1, 250);
+ TestFileAccount.Insert();
+
+ FileAccount."Account Id" := TestFileAccount.Id;
+ FileAccount.Name := TestFileAccount.Name;
+ FileAccount.Connector := Enum::"File System Connector"::"Test File System Connector";
+ end;
+
+ procedure AddAccount(var Id: Guid)
+ var
+ TestFileAccount: Record "Test File Account";
+ begin
+ TestFileAccount.Id := Any.GuidValue();
+ TestFileAccount.Name := CopyStr(Any.AlphanumericText(250), 1, 250);
+ TestFileAccount.Insert();
+
+ Id := TestFileAccount.Id;
+ end;
+
+ procedure FailOnSend(): Boolean
+ var
+ TestFileConnectorSetup: Record "Test File Connector Setup";
+ begin
+ TestFileConnectorSetup.FindFirst();
+ exit(TestFileConnectorSetup."Fail On Send");
+ end;
+
+ procedure FailOnSend(Fail: Boolean)
+ var
+ TestFileConnectorSetup: Record "Test File Connector Setup";
+ begin
+ TestFileConnectorSetup.FindFirst();
+ TestFileConnectorSetup."Fail On Send" := Fail;
+ TestFileConnectorSetup.Modify();
+ end;
+
+ procedure FailOnRegisterAccount(): Boolean
+ var
+ TestFileConnectorSetup: Record "Test File Connector Setup";
+ begin
+ TestFileConnectorSetup.FindFirst();
+ exit(TestFileConnectorSetup."Fail On Register Account");
+ end;
+
+ procedure FailOnRegisterAccount(Fail: Boolean)
+ var
+ TestFileConnectorSetup: Record "Test File Connector Setup";
+ begin
+ TestFileConnectorSetup.FindFirst();
+ TestFileConnectorSetup."Fail On Register Account" := Fail;
+ TestFileConnectorSetup.Modify();
+ end;
+
+ procedure UnsuccessfulRegister(): Boolean
+ var
+ TestFileConnectorSetup: Record "Test File Connector Setup";
+ begin
+ TestFileConnectorSetup.FindFirst();
+ exit(TestFileConnectorSetup."Unsuccessful Register");
+ end;
+
+ procedure UnsuccessfulRegister(Fail: Boolean)
+ var
+ TestFileConnectorSetup: Record "Test File Connector Setup";
+ begin
+ TestFileConnectorSetup.FindFirst();
+ TestFileConnectorSetup."Unsuccessful Register" := Fail;
+ TestFileConnectorSetup.Modify();
+ end;
+
+ procedure SetEmailMessageID(EmailMessageID: Guid)
+ var
+ TestFileConnectorSetup: Record "Test File Connector Setup";
+ begin
+ TestFileConnectorSetup.FindFirst();
+ TestFileConnectorSetup."Email Message ID" := EmailMessageID;
+ TestFileConnectorSetup.Modify();
+ end;
+
+ procedure GetEmailMessageID(): Guid
+ var
+ TestFileConnectorSetup: Record "Test File Connector Setup";
+ begin
+ TestFileConnectorSetup.FindFirst();
+ exit(TestFileConnectorSetup."Email Message ID");
+ end;
+}
\ No newline at end of file
diff --git a/src/System Application/Test Library/File System/src/FileScenarioMock.Codeunit.al b/src/System Application/Test Library/File System/src/FileScenarioMock.Codeunit.al
new file mode 100644
index 0000000000..47a53ada2b
--- /dev/null
+++ b/src/System Application/Test Library/File System/src/FileScenarioMock.Codeunit.al
@@ -0,0 +1,32 @@
+// ------------------------------------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License. See License.txt in the project root for license information.
+// ------------------------------------------------------------------------------------------------
+
+namespace System.TestLibraries.FileSystem;
+
+using System.FileSystem;
+
+codeunit 80201 "File Scenario Mock"
+{
+ Permissions = tabledata "File Scenario" = rid;
+
+ procedure AddMapping(FileScenario: Enum "File Scenario"; AccountId: Guid; Connector: Enum "File System Connector")
+ var
+ Scenario: Record "File Scenario";
+ begin
+ Scenario.Scenario := FileScenario;
+ Scenario."Account Id" := AccountId;
+ Scenario.Connector := Connector;
+
+ Scenario.Insert();
+ end;
+
+ procedure DeleteAllMappings()
+ var
+ Scenario: Record "File Scenario";
+ begin
+ Scenario.DeleteAll();
+ end;
+
+}
\ No newline at end of file
diff --git a/src/System Application/Test Library/File System/src/TestFileAccount.Table.al b/src/System Application/Test Library/File System/src/TestFileAccount.Table.al
new file mode 100644
index 0000000000..c7cb6c0898
--- /dev/null
+++ b/src/System Application/Test Library/File System/src/TestFileAccount.Table.al
@@ -0,0 +1,33 @@
+// ------------------------------------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License. See License.txt in the project root for license information.
+// ------------------------------------------------------------------------------------------------
+
+namespace System.TestLibraries.FileSystem;
+
+table 80200 "Test File Account"
+{
+ DataClassification = SystemMetadata;
+ ReplicateData = false;
+
+ fields
+ {
+ field(1; Id; Guid)
+ {
+ Caption = 'Primary Key';
+ }
+
+ field(2; Name; Text[250])
+ {
+ Caption = 'Name';
+ }
+ }
+
+ keys
+ {
+ key(PK; Id)
+ {
+ Clustered = true;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/System Application/Test Library/File System/src/TestFileConnectorSetup.Table.al b/src/System Application/Test Library/File System/src/TestFileConnectorSetup.Table.al
new file mode 100644
index 0000000000..6e23878497
--- /dev/null
+++ b/src/System Application/Test Library/File System/src/TestFileConnectorSetup.Table.al
@@ -0,0 +1,44 @@
+// ------------------------------------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License. See License.txt in the project root for license information.
+// ------------------------------------------------------------------------------------------------
+
+namespace System.TestLibraries.FileSystem;
+
+table 80201 "Test File Connector Setup"
+{
+ DataClassification = SystemMetadata;
+ ReplicateData = false;
+
+ fields
+ {
+ field(1; Id; Guid)
+ {
+ Caption = 'Primary Key';
+ }
+ field(2; "Fail On Send"; Boolean)
+ {
+ Caption = 'Fail On Send';
+ }
+ field(3; "Fail On Register Account"; Boolean)
+ {
+ Caption = 'Fail On Register Account';
+ }
+ field(4; "Unsuccessful Register"; Boolean)
+ {
+ Caption = 'Unsuccessful Register';
+ }
+ field(5; "Email Message ID"; Guid)
+ {
+ Caption = 'Email Message ID';
+ }
+ }
+
+ keys
+ {
+ key(PK; Id)
+ {
+ Clustered = true;
+ }
+ }
+}
diff --git a/src/System Application/Test Library/File System/src/TestFileScenario.EnumExt.al b/src/System Application/Test Library/File System/src/TestFileScenario.EnumExt.al
new file mode 100644
index 0000000000..b62b61a743
--- /dev/null
+++ b/src/System Application/Test Library/File System/src/TestFileScenario.EnumExt.al
@@ -0,0 +1,15 @@
+// ------------------------------------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License. See License.txt in the project root for license information.
+// ------------------------------------------------------------------------------------------------
+
+namespace System.TestLibraries.FileSystem;
+
+using System.FileSystem;
+
+enumextension 80200 "Test File Scenario" extends "File Scenario"
+{
+ value(80200; "Test File Scenario")
+ {
+ }
+}
\ No newline at end of file
diff --git a/src/System Application/Test Library/File System/src/TestFileSystemConnector.Codeunit.al b/src/System Application/Test Library/File System/src/TestFileSystemConnector.Codeunit.al
new file mode 100644
index 0000000000..4d1dca2512
--- /dev/null
+++ b/src/System Application/Test Library/File System/src/TestFileSystemConnector.Codeunit.al
@@ -0,0 +1,136 @@
+// ------------------------------------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License. See License.txt in the project root for license information.
+// ------------------------------------------------------------------------------------------------
+
+namespace System.TestLibraries.FileSystem;
+
+using System.FileSystem;
+
+codeunit 80202 "Test File System Connector" implements "File System Connector"
+{
+ /*
+ procedure Send(EmailMessage: Codeunit "Email Message"; AccountId: Guid)
+ begin
+ ConnectorMock.SetEmailMessageID(EmailMessage.GetId());
+ Commit();
+ if ConnectorMock.FailOnSend() then
+ Error('Failed to send email');
+ end;
+*/
+
+ procedure ListFiles(AccountId: Guid; Path: Text; FilePaginationData: Codeunit "File Pagination Data"; var FileAccountContent: Record "File Account Content" temporary);
+ begin
+ FileAccountContent.Init();
+ FileAccountContent.Type := FileAccountContent.Type::Directory;
+ FileAccountContent.Name := 'Test Folder';
+ FileAccountContent.Insert();
+
+ FileAccountContent.Init();
+ FileAccountContent.Type := FileAccountContent.Type::File;
+ FileAccountContent.Name := 'Test.pdf';
+ FileAccountContent.Insert();
+ end;
+
+ procedure GetFile(AccountId: Guid; Path: Text; Stream: InStream);
+ begin
+
+ end;
+
+ procedure SetFile(AccountId: Guid; Path: Text; Stream: InStream);
+ begin
+
+ end;
+
+ procedure CopyFile(AccountId: Guid; SourcePath: Text; TargetPath: Text);
+ begin
+
+ end;
+
+ procedure MoveFile(AccountId: Guid; SourcePath: Text; TargetPath: Text);
+ begin
+
+ end;
+
+ procedure FileExists(AccountId: Guid; Path: Text): Boolean;
+ begin
+
+ end;
+
+ procedure DeleteFile(AccountId: Guid; Path: Text);
+ begin
+
+ end;
+
+ procedure ListDirectories(AccountId: Guid; Path: Text; FilePaginationData: Codeunit "File Pagination Data"; var FileAccountContent: Record "File Account Content" temporary);
+ begin
+
+ end;
+
+ procedure CreateDirectory(AccountId: Guid; Path: Text);
+ begin
+
+ end;
+
+ procedure DirectoryExists(AccountId: Guid; Path: Text): Boolean;
+ begin
+
+ end;
+
+ procedure DeleteDirectory(AccountId: Guid; Path: Text);
+ begin
+
+ end;
+
+ procedure PathSeparator(): Text;
+ begin
+
+ end;
+
+ procedure GetAccounts(var Accounts: Record "File Account")
+ begin
+ ConnectorMock.GetAccounts(Accounts);
+ end;
+
+ procedure ShowAccountInformation(AccountId: Guid)
+ begin
+ Message('Showing information for account: %1', AccountId);
+ end;
+
+ procedure RegisterAccount(var FileAccount: Record "File Account"): Boolean
+ var
+ begin
+ if ConnectorMock.FailOnRegisterAccount() then
+ Error('Failed to register account');
+
+ if ConnectorMock.UnsuccessfulRegister() then
+ exit(false);
+
+ FileAccount."Account Id" := CreateGuid();
+ FileAccount.Name := 'Test account';
+
+ exit(true);
+ end;
+
+ procedure DeleteAccount(AccountId: Guid): Boolean
+ var
+ TestFileAccount: Record "Test File Account";
+ begin
+ if TestFileAccount.Get(AccountId) then
+ exit(TestFileAccount.Delete());
+ exit(false);
+ end;
+
+ procedure GetLogoAsBase64(): Text
+ begin
+
+ end;
+
+ procedure GetDescription(): Text[250]
+ begin
+ exit('Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis ornare ante a est commodo interdum. Pellentesque eu diam maximus, faucibus neque ut, viverra leo. Praesent ullamcorper nibh ut pretium dapibus. Nullam eu dui libero. Etiam ac cursus metus.')
+ end;
+
+ var
+ ConnectorMock: Codeunit "Connector Mock";
+}
\ No newline at end of file
diff --git a/src/System Application/Test Library/File System/src/TestFileSystemConnector.EnumExt.al b/src/System Application/Test Library/File System/src/TestFileSystemConnector.EnumExt.al
new file mode 100644
index 0000000000..62e25b5415
--- /dev/null
+++ b/src/System Application/Test Library/File System/src/TestFileSystemConnector.EnumExt.al
@@ -0,0 +1,16 @@
+// ------------------------------------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License. See License.txt in the project root for license information.
+// ------------------------------------------------------------------------------------------------
+
+namespace System.TestLibraries.FileSystem;
+
+using System.FileSystem;
+
+enumextension 80201 "Test File System Connector" extends "File System Connector"
+{
+ value(80200; "Test File System Connector")
+ {
+ Implementation = "File System Connector" = "Test File System Connector";
+ }
+}
\ No newline at end of file
diff --git a/src/System Application/Test/File System/app.json b/src/System Application/Test/File System/app.json
new file mode 100644
index 0000000000..e6c9d1544d
--- /dev/null
+++ b/src/System Application/Test/File System/app.json
@@ -0,0 +1,105 @@
+{
+ "id": "fff6eee5-083f-4f07-9a49-e34f7e2aad77",
+ "name": "File System Test",
+ "publisher": "Microsoft",
+ "brief": "Tests for the File System module",
+ "description": "Tests for the File System module",
+ "version": "25.0.0.0",
+ "privacyStatement": "https://go.microsoft.com/fwlink/?linkid=724009",
+ "EULA": "https://go.microsoft.com/fwlink/?linkid=2009120",
+ "help": "https://go.microsoft.com/fwlink/?linkid=2103698",
+ "url": "https://go.microsoft.com/fwlink/?linkid=724011",
+ "logo": "",
+ "dependencies": [
+ {
+ "id": "c9c54414-80c3-4cc9-98c6-589158882774",
+ "name": "File System",
+ "publisher": "Microsoft",
+ "version": "25.0.0.0"
+ },
+ {
+ "id": "f188754b-3ffb-443a-9507-f5fbdae3af2c",
+ "name": "File System Test Library",
+ "publisher": "Microsoft",
+ "version": "25.0.0.0"
+ },
+ {
+ "id": "47397d83-32ba-4ef0-8988-ef72539bfe36",
+ "name": "Client Type Management Test Library",
+ "publisher": "Microsoft",
+ "version": "25.0.0.0"
+ },
+ {
+ "id": "5095f467-0a01-4b99-99d1-9ff1237d286f",
+ "name": "Library Variable Storage",
+ "publisher": "Microsoft",
+ "version": "25.0.0.0"
+ },
+ {
+ "id": "e31ad830-3d46-472e-afeb-1d3d35247943",
+ "name": "BLOB Storage",
+ "publisher": "Microsoft",
+ "version": "25.0.0.0"
+ },
+ {
+ "id": "0846d207-5dec-4c1b-afd8-6a25e1e14b9d",
+ "name": "Base64 Convert",
+ "publisher": "Microsoft",
+ "version": "25.0.0.0"
+ },
+ {
+ "id": "dd0be2ea-f733-4d65-bb34-a28f4624fb14",
+ "name": "Library Assert",
+ "publisher": "Microsoft",
+ "version": "25.0.0.0"
+ },
+ {
+ "id": "e7320ebb-08b3-4406-b1ec-b4927d3e280b",
+ "name": "Any",
+ "publisher": "Microsoft",
+ "version": "25.0.0.0"
+ },
+ {
+ "id": "40860557-a18d-42ad-aecb-22b7dd80dc80",
+ "name": "Permissions Mock",
+ "publisher": "Microsoft",
+ "version": "25.0.0.0"
+ }
+ ],
+ "screenshots": [
+
+ ],
+ "platform": "25.0.0.0",
+ "idRanges": [
+ {
+ "from": 134487,
+ "to": 134487
+ },
+ {
+ "from": 134683,
+ "to": 134689
+ },
+ {
+ "from": 134692,
+ "to": 134699
+ },
+ {
+ "from": 134701,
+ "to": 134701
+ },
+ {
+ "from": 134852,
+ "to": 134852
+ },
+ {
+ "from": 134853,
+ "to": 134853
+ },
+ {
+ "from": 134705,
+ "to": 134706
+ }
+ ],
+ "contextSensitiveHelpUrl": "https://go.microsoft.com/fwlink/?linkid=2134520",
+ "target": "OnPrem"
+}
\ No newline at end of file
diff --git a/src/System Application/Test/File System/src/FileAccountsTest.Codeunit.al b/src/System Application/Test/File System/src/FileAccountsTest.Codeunit.al
new file mode 100644
index 0000000000..b0d917430f
--- /dev/null
+++ b/src/System Application/Test/File System/src/FileAccountsTest.Codeunit.al
@@ -0,0 +1,638 @@
+// ------------------------------------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License. See License.txt in the project root for license information.
+// ------------------------------------------------------------------------------------------------
+
+namespace System.Test.FileSystem;
+
+using System.FileSystem;
+using System.TestLibraries.FileSystem;
+using System.TestLibraries.Utilities;
+using System.TestLibraries.Security.AccessControl;
+
+codeunit 134686 "File Accounts Test"
+{
+ Subtype = Test;
+ TestPermissions = Disabled;
+
+ var
+ Assert: Codeunit "Library Assert";
+ PermissionsMock: Codeunit "Permissions Mock";
+ AccountToSelect: Guid;
+ AccountNameLbl: Label '%1 (%2)', Locked = true;
+
+ [Test]
+ [Scope('OnPrem')]
+ [TransactionModel(TransactionModel::AutoRollback)]
+ procedure AccountsAppearOnThePageTest()
+ var
+ FileAccount: Record "File Account";
+ ConnectorMock: Codeunit "Connector Mock";
+ AccountsPage: TestPage "File Accounts";
+ begin
+ // [Scenario] When there's a File account for a connector, it appears on the accounts page
+
+ // [Given] A File account
+ ConnectorMock.Initialize();
+ ConnectorMock.AddAccount(FileAccount);
+
+ PermissionsMock.Set('File Edit');
+
+ // [When] The accounts page is open
+ AccountsPage.OpenView();
+
+ // [Then] The email entry is visible on the page
+ Assert.IsTrue(AccountsPage.GoToKey(FileAccount."Account Id", FileAccount.Connector), 'The File account should be on the page');
+
+ Assert.AreEqual(FileAccount.Name, Format(AccountsPage.NameField), 'The account name on the page is wrong');
+ end;
+
+ [Test]
+ [Scope('OnPrem')]
+ [TransactionModel(TransactionModel::AutoRollback)]
+ procedure TwoAccountsAppearOnThePageTest()
+ var
+ FirstEmailAccount, SecondEmailAccount : Record "File Account";
+ ConnectorMock: Codeunit "Connector Mock";
+ AccountsPage: TestPage "File Accounts";
+ begin
+ // [Scenario] When there's a File account for a connector, it appears on the accounts page
+
+ // [Given] Two File accounts
+ ConnectorMock.Initialize();
+ ConnectorMock.AddAccount(FirstEmailAccount);
+ ConnectorMock.AddAccount(SecondEmailAccount);
+
+ PermissionsMock.Set('Email Edit');
+
+ // [When] The accounts page is open
+ AccountsPage.OpenView();
+
+ // [Then] The email entries are visible on the page
+ Assert.IsTrue(AccountsPage.GoToKey(FirstEmailAccount."Account Id", Enum::"File System Connector"::"Test File System Connector"), 'The first File account should be on the page');
+ Assert.AreEqual(FirstEmailAccount.Name, Format(AccountsPage.NameField), 'The first account name on the page is wrong');
+
+ Assert.IsTrue(AccountsPage.GoToKey(SecondEmailAccount."Account Id", Enum::"File System Connector"::"Test File System Connector"), 'The second File account should be on the page');
+ Assert.AreEqual(SecondEmailAccount.Name, Format(AccountsPage.NameField), 'The second account name on the page is wrong');
+ end;
+
+ [Test]
+ [TransactionModel(TransactionModel::AutoRollback)]
+ procedure IsAccountRegisteredTest()
+ var
+ EmailAccountRecord: Record "File Account";
+ ConnectorMock: Codeunit "Connector Mock";
+ EmailAccount: Codeunit "File Account";
+ begin
+ // [Scenario] When there's a File account for a connector, it should return true for IsAccountRegistered
+
+ // [Given] An File account
+ ConnectorMock.Initialize();
+ ConnectorMock.AddAccount(EmailAccountRecord);
+
+ PermissionsMock.Set('Email Edit');
+
+ // [Then] The File account is registered
+ Assert.IsTrue(EmailAccount.IsAccountRegistered(EmailAccountRecord."Account Id", EmailAccountRecord.Connector), 'The File account should be registered');
+ end;
+
+ [Test]
+ [Scope('OnPrem')]
+ [TransactionModel(TransactionModel::AutoRollback)]
+ procedure AddNewAccountTest()
+ var
+ ConnectorMock: Codeunit "Connector Mock";
+ AccountWizardPage: TestPage "File Account Wizard";
+ begin
+ // [SCENARIO] A new Account can be added through the Account Wizard
+ PermissionsMock.Set('Email Admin');
+
+ ConnectorMock.Initialize();
+
+ // [WHEN] The AddAccount action is invoked
+ AccountWizardPage.Trap();
+ Page.Run(Page::"File Account Wizard");
+
+ // [WHEN] The next field is invoked
+ AccountWizardPage.Next.Invoke();
+
+ // [THEN] The connector screen is shown and the test connector is shown
+ Assert.IsTrue(AccountWizardPage.Logo.Visible(), 'Connector Logo should be visible');
+ Assert.IsTrue(AccountWizardPage.Name.Visible(), 'Connector Name should be visible');
+ Assert.IsTrue(AccountWizardPage.Details.Visible(), 'Connector Details should be visible');
+
+ Assert.IsTrue(AccountWizardPage.GoToKey(Enum::"File System Connector"::"Test File System Connector"), 'Test Email connector was not shown in the page');
+
+ // [WHEN] The Name field is drilled down
+ AccountWizardPage.Next.Invoke();
+
+ // [THEN] The Connector registers the Account and the last page is shown
+ Assert.AreEqual(AccountWizardPage.EmailAddressfield.Value(), 'Test email address', 'A different Email address was expected');
+ Assert.AreEqual(AccountWizardPage.NameField.Value(), 'Test account', 'A different name was expected');
+ Assert.AreEqual(AccountWizardPage.DefaultField.AsBoolean(), true, 'Default should be set to true if it''s the first account to be set up');
+ end;
+
+ [Test]
+ [Scope('OnPrem')]
+ [TransactionModel(TransactionModel::AutoRollback)]
+ [HandlerFunctions('AddAccountModalPageHandler')]
+ procedure AddNewAccountActionRunsPageInModalTest()
+ var
+ AccountsPage: TestPage "File Accounts";
+ begin
+ // [SCENARIO] The add Account action open the Account Wizard page in modal mode
+ PermissionsMock.Set('Email Admin');
+
+ AccountsPage.OpenView();
+ // [WHEN] The AddAccount action is invoked
+ AccountsPage.AddAccount.Invoke();
+
+ // Verify with AddAccountModalPageHandler
+ end;
+
+ [Test]
+ procedure OpenEditorFromAccountsPageTest()
+ var
+ TempAccount: Record "File Account" temporary;
+ ConnectorMock: Codeunit "Connector Mock";
+ Accounts: TestPage "File Accounts";
+ Editor: TestPage "Email Editor";
+ begin
+ // [SCENARIO] Email editor page can be opened from the Accounts page
+ Editor.Trap();
+ // [GIVEN] A connector is installed and an account is added
+ ConnectorMock.Initialize();
+ ConnectorMock.AddAccount(TempAccount);
+
+ PermissionsMock.Set('Email Edit');
+
+ // [WHEN] The Send Email action is invoked
+ Accounts.OpenView();
+ Accounts.GoToKey(TempAccount."Account Id", TempAccount.Connector);
+ Accounts.SendEmail.Invoke();
+
+ // [THEN] The Editor page opens to create a new message
+ Assert.AreEqual(StrSubstNo(AccountNameLbl, TempAccount.Name, TempAccount."Email Address"), Editor.Account.Value(), 'A different from was expected.');
+ end;
+
+ [Test]
+ procedure OpenSentMailsFromAccountsPageTest()
+ var
+ TempAccount: Record "File Account" temporary;
+ ConnectorMock: Codeunit "Connector Mock";
+ Accounts: TestPage "File Accounts";
+ SentEmails: TestPage "Sent Emails";
+ begin
+ // [SCENARIO] Sent emails page can be opened from the Accounts page
+ SentEmails.Trap();
+ // [GIVEN] A connector is installed and an account is added
+ ConnectorMock.Initialize();
+ ConnectorMock.AddAccount(TempAccount);
+
+ PermissionsMock.Set('Email Edit');
+
+ // [WHEN] The Sent Emails action is invoked
+ Accounts.OpenView();
+ Accounts.SentEmails.Invoke();
+
+ // [THEN] The sent emails page opens
+ // Verify with Trap
+ end;
+
+ [Test]
+ procedure OpenOutBoxFromAccountsPageTest()
+ var
+ TempAccount: Record "File Account" temporary;
+ ConnectorMock: Codeunit "Connector Mock";
+ Accounts: TestPage "File Accounts";
+ Outbox: TestPage "Email Outbox";
+ begin
+ // [SCENARIO] Outbox page can be opened from the Accounts page
+ Outbox.Trap();
+ // [GIVEN] A connector is installed and an account is added
+ ConnectorMock.Initialize();
+ ConnectorMock.AddAccount(TempAccount);
+
+ PermissionsMock.Set('Email Edit');
+
+ // [WHEN] The Outbox action is invoked
+ Accounts.OpenView();
+ Accounts.Outbox.Invoke();
+
+ // [THEN] The outbox page opens
+ // Verify with Trap
+ end;
+
+ [Test]
+ procedure GetAllAccountsTest()
+ var
+ EmailAccountBuffer, EmailAccounts : Record "File Account";
+ ConnectorMock: Codeunit "Connector Mock";
+ EmailAccount: Codeunit "File Account";
+ begin
+ // [SCENARIO] GetAllAccounts retrieves all the registered accounts
+
+ // [GIVEN] A connector is installed and no account is added
+ ConnectorMock.Initialize();
+
+ PermissionsMock.Set('Email Edit');
+
+ // [WHEN] GetAllAccounts is called
+ EmailAccount.GetAllAccounts(EmailAccounts);
+
+ // [THEN] The returned record is empty (there are no registered accounts)
+ Assert.IsTrue(EmailAccounts.IsEmpty(), 'Record should be empty');
+
+ // [GIVEN] An account is added to the connector
+ ConnectorMock.AddAccount(EmailAccountBuffer);
+
+ // [WHEN] GetAllAccounts is called
+ EmailAccount.GetAllAccounts(EmailAccounts);
+
+ // [THEN] The returned record is not empty and the values are as expected
+ Assert.AreEqual(1, EmailAccounts.Count(), 'Record should not be empty');
+ EmailAccounts.FindFirst();
+ Assert.AreEqual(EmailAccountBuffer."Account Id", EmailAccounts."Account Id", 'Wrong account ID');
+ Assert.AreEqual(Enum::"File System Connector"::"Test File System Connector", EmailAccounts.Connector, 'Wrong connector');
+ Assert.AreEqual(EmailAccountBuffer.Name, EmailAccounts.Name, 'Wrong account name');
+ end;
+
+ [Test]
+ procedure IsAnyAccountRegisteredTest()
+ var
+ ConnectorMock: Codeunit "Connector Mock";
+ EmailAccount: Codeunit "File Account";
+ AccountId: Guid;
+ begin
+ // [SCENARIO] File Account Exists works as expected
+
+ // [GIVEN] A connector is installed and no account is added
+ ConnectorMock.Initialize();
+
+ PermissionsMock.Set('Email Edit');
+
+ // [WHEN] Calling IsAnyAccountRegistered
+ // [THEN] it evaluates to false
+ Assert.IsFalse(EmailAccount.IsAnyAccountRegistered(), 'There should be no registered accounts');
+
+ // [WHEN] An File account is added
+ ConnectorMock.AddAccount(AccountId);
+
+ // [WHEN] Calling IsAnyAccountRegistered
+ // [THEN] it evaluates to true
+ Assert.IsTrue(EmailAccount.IsAnyAccountRegistered(), 'There should be a registered account');
+ end;
+
+ [Test]
+ [HandlerFunctions('ConfirmYesHandler')]
+ procedure DeleteAllAccountsTest()
+ var
+ ConnectorMock: Codeunit "Connector Mock";
+ EmailAccountsSelectionMock: Codeunit "File System Acc Selection Mock";
+ FirstAccountId, SecondAccountId, ThirdAccountId : Guid;
+ EmailAccountsTestPage: TestPage "File Accounts";
+ begin
+ // [SCENARIO] When all accounts are deleted, the File Accounts page is empty
+ PermissionsMock.Set('Email Admin');
+
+ // [GIVEN] A connector is installed and three account are added
+ ConnectorMock.Initialize();
+ ConnectorMock.AddAccount(FirstAccountId);
+ ConnectorMock.AddAccount(SecondAccountId);
+ ConnectorMock.AddAccount(ThirdAccountId);
+
+ // [WHEN] Open the File Accounts page
+ EmailAccountsTestPage.OpenView();
+
+ // [WHEN] Select all of the accounts
+ BindSubscription(EmailAccountsSelectionMock);
+ EmailAccountsSelectionMock.SelectAccount(FirstAccountId);
+ EmailAccountsSelectionMock.SelectAccount(SecondAccountId);
+ EmailAccountsSelectionMock.SelectAccount(ThirdAccountId);
+
+ // [WHEN] Delete action is invoked and the action is confirmed (see ConfirmYesHandler)
+ EmailAccountsTestPage.Delete.Invoke();
+
+ // [THEN] The page is empty
+ Assert.IsFalse(EmailAccountsTestPage.First(), 'The File Accounts page should be empty');
+ end;
+
+ [Test]
+ [HandlerFunctions('ConfirmNoHandler')]
+ procedure DeleteAllAccountsCancelTest()
+ var
+ ConnectorMock: Codeunit "Connector Mock";
+ EmailAccountsSelectionMock: Codeunit "File System Acc Selection Mock";
+ FirstAccountId, SecondAccountId, ThirdAccountId : Guid;
+ EmailAccountsTestPage: TestPage "File Accounts";
+ begin
+ // [SCENARIO] When all accounts are about to be deleted but the action in canceled, the File Accounts page contains all of them.
+ PermissionsMock.Set('Email Admin');
+
+ // [GIVEN] A connector is installed and three account are added
+ ConnectorMock.Initialize();
+ ConnectorMock.AddAccount(FirstAccountId);
+ ConnectorMock.AddAccount(SecondAccountId);
+ ConnectorMock.AddAccount(ThirdAccountId);
+
+ // [WHEN] Open the File Accounts page
+ EmailAccountsTestPage.OpenView();
+
+ // [WHEN] Select all of the accounts
+ BindSubscription(EmailAccountsSelectionMock);
+ EmailAccountsSelectionMock.SelectAccount(FirstAccountId);
+ EmailAccountsSelectionMock.SelectAccount(SecondAccountId);
+ EmailAccountsSelectionMock.SelectAccount(ThirdAccountId);
+
+ // [WHEN] Delete action is invoked and the action is not confirmed (see ConfirmNoHandler)
+ EmailAccountsTestPage.Delete.Invoke();
+
+ // [THEN] All of the accounts are on the page
+ Assert.IsTrue(EmailAccountsTestPage.GoToKey(FirstAccountId, Enum::"File System Connector"::"Test File System Connector"), 'The first File account should be on the page');
+ Assert.IsTrue(EmailAccountsTestPage.GoToKey(SecondAccountId, Enum::"File System Connector"::"Test File System Connector"), 'The second File account should be on the page');
+ Assert.IsTrue(EmailAccountsTestPage.GoToKey(ThirdAccountId, Enum::"File System Connector"::"Test File System Connector"), 'The third File account should be on the page');
+ end;
+
+ [Test]
+ [HandlerFunctions('ConfirmYesHandler')]
+ procedure DeleteSomeAccountsTest()
+ var
+ ConnectorMock: Codeunit "Connector Mock";
+ EmailAccountsSelectionMock: Codeunit "File System Acc Selection Mock";
+ FirstAccountId, SecondAccountId, ThirdAccountId : Guid;
+ EmailAccountsTestPage: TestPage "File Accounts";
+ begin
+ // [SCENARIO] When some accounts are deleted, they cannot be found on the page
+ PermissionsMock.Set('Email Admin');
+
+ // [GIVEN] A connector is installed and three account are added
+ ConnectorMock.Initialize();
+ ConnectorMock.AddAccount(FirstAccountId);
+ ConnectorMock.AddAccount(SecondAccountId);
+ ConnectorMock.AddAccount(ThirdAccountId);
+
+ // [WHEN] Open the File Accounts page
+ EmailAccountsTestPage.OpenView();
+
+ // [WHEN] Select only two of the accounts
+ BindSubscription(EmailAccountsSelectionMock);
+ EmailAccountsSelectionMock.SelectAccount(FirstAccountId);
+ EmailAccountsSelectionMock.SelectAccount(ThirdAccountId);
+
+ // [WHEN] Delete action is invoked and the action is confirmed (see ConfirmYesHandler)
+ EmailAccountsTestPage.Delete.Invoke();
+
+ // [THEN] The deleted accounts are not on the page, the non-deleted accounts are on the page.
+ Assert.IsFalse(EmailAccountsTestPage.GoToKey(FirstAccountId, Enum::"File System Connector"::"Test File System Connector"), 'The first File account should not be on the page');
+ Assert.IsTrue(EmailAccountsTestPage.GoToKey(SecondAccountId, Enum::"File System Connector"::"Test File System Connector"), 'The second File account should be on the page');
+ Assert.IsFalse(EmailAccountsTestPage.GoToKey(ThirdAccountId, Enum::"File System Connector"::"Test File System Connector"), 'The third File account should not be on the page');
+ end;
+
+ [Test]
+ [HandlerFunctions('ConfirmYesHandler')]
+ procedure DeleteNonDefaultAccountTest()
+ var
+ SecondAccount: Record "File Account";
+ ConnectorMock: Codeunit "Connector Mock";
+ EmailAccountsSelectionMock: Codeunit "File System Acc Selection Mock";
+ EmailScenario: Codeunit "File Scenario";
+ FirstAccountId, ThirdAccountId : Guid;
+ EmailAccountsTestPage: TestPage "File Accounts";
+ begin
+ // [SCENARIO] When the a non default account is deleted, the user is not prompted to choose a new default account.
+ PermissionsMock.Set('Email Admin');
+
+ // [GIVEN] A connector is installed and three account are added
+ ConnectorMock.Initialize();
+ ConnectorMock.AddAccount(FirstAccountId);
+ ConnectorMock.AddAccount(SecondAccount);
+ ConnectorMock.AddAccount(ThirdAccountId);
+
+ // [GIVEN] The second account is set as default
+ EmailScenario.SetDefaultFileAccount(SecondAccount);
+
+ // [WHEN] Open the File Accounts page
+ EmailAccountsTestPage.OpenView();
+
+ // [WHEN] Select a non-default account
+ BindSubscription(EmailAccountsSelectionMock);
+ EmailAccountsSelectionMock.SelectAccount(FirstAccountId);
+
+ // [WHEN] Delete action is invoked and the action is confirmed (see ConfirmYesHandler)
+ EmailAccountsTestPage.Delete.Invoke();
+
+ // [THEN] The deleted accounts are not on the page, the non-deleted accounts are on the page.
+ Assert.IsFalse(EmailAccountsTestPage.GoToKey(FirstAccountId, Enum::"File System Connector"::"Test File System Connector"), 'The first File account should not be on the page');
+
+ Assert.IsTrue(EmailAccountsTestPage.GoToKey(SecondAccount."Account Id", Enum::"File System Connector"::"Test File System Connector"), 'The second File account should be on the page');
+ Assert.IsTrue(GetDefaultFieldValueAsBoolean(EmailAccountsTestPage.DefaultField.Value), 'The second account should be marked as default');
+
+ Assert.IsTrue(EmailAccountsTestPage.GoToKey(ThirdAccountId, Enum::"File System Connector"::"Test File System Connector"), 'The third File account should be on the page');
+ Assert.IsFalse(GetDefaultFieldValueAsBoolean(EmailAccountsTestPage.DefaultField.Value), 'The third account should not be marked as default');
+ end;
+
+ [Test]
+ [HandlerFunctions('ConfirmYesHandler')]
+ procedure DeleteDefaultAccountTest()
+ var
+ SecondAccount: Record "File Account";
+ ConnectorMock: Codeunit "Connector Mock";
+ EmailAccountsSelectionMock: Codeunit "File System Acc Selection Mock";
+ EmailScenario: Codeunit "File Scenario";
+ FirstAccountId, ThirdAccountId : Guid;
+ EmailAccountsTestPage: TestPage "File Accounts";
+ begin
+ // [SCENARIO] When the default account is deleted, the user is not prompted to choose a new default account if there's only one account left
+ PermissionsMock.Set('Email Admin');
+
+ // [GIVEN] A connector is installed and three account are added
+ ConnectorMock.Initialize();
+ ConnectorMock.AddAccount(FirstAccountId);
+ ConnectorMock.AddAccount(SecondAccount);
+ ConnectorMock.AddAccount(ThirdAccountId);
+
+ // [GIVEN] The second account is set as default
+ EmailScenario.SetDefaultFileAccount(SecondAccount);
+
+ // [WHEN] Open the File Accounts page
+ EmailAccountsTestPage.OpenView();
+
+ // [WHEN] Select accounts including the default one
+ BindSubscription(EmailAccountsSelectionMock);
+ EmailAccountsSelectionMock.SelectAccount(SecondAccount."Account Id");
+ EmailAccountsSelectionMock.SelectAccount(ThirdAccountId);
+
+ // [WHEN] Delete action is invoked and the action is confirmed (see ConfirmYesHandler)
+ EmailAccountsTestPage.Delete.Invoke();
+
+ // [THEN] The deleted accounts are not on the page, the non-deleted accounts are on the page.
+ Assert.IsTrue(EmailAccountsTestPage.GoToKey(FirstAccountId, Enum::"File System Connector"::"Test File System Connector"), 'The first File account should be on the page');
+ Assert.IsTrue(GetDefaultFieldValueAsBoolean(EmailAccountsTestPage.DefaultField.Value), 'The first account should be marked as default');
+
+ Assert.IsFalse(EmailAccountsTestPage.GoToKey(SecondAccount."Account Id", Enum::"File System Connector"::"Test File System Connector"), 'The second File account should not be on the page');
+ Assert.IsFalse(EmailAccountsTestPage.GoToKey(ThirdAccountId, Enum::"File System Connector"::"Test File System Connector"), 'The third File account should not be on the page');
+ end;
+
+ [Test]
+ [HandlerFunctions('ConfirmYesHandler,ChooseNewDefaultAccountCancelHandler')]
+ procedure DeleteDefaultAccountPromptNewAccountCancelTest()
+ var
+ SecondAccount: Record "File Account";
+ ConnectorMock: Codeunit "Connector Mock";
+ EmailAccountsSelectionMock: Codeunit "File System Acc Selection Mock";
+ EmailScenario: Codeunit "File Scenario";
+ FirstAccountId, ThirdAccountId : Guid;
+ EmailAccountsTestPage: TestPage "File Accounts";
+ begin
+ // [SCENARIO] When the default account is deleted, the user is prompted to choose a new default account but they cancel.
+ PermissionsMock.Set('Email Admin');
+
+ // [GIVEN] A connector is installed and three account are added
+ ConnectorMock.Initialize();
+ ConnectorMock.AddAccount(FirstAccountId);
+ ConnectorMock.AddAccount(SecondAccount);
+ ConnectorMock.AddAccount(ThirdAccountId);
+
+ // [GIVEN] The second account is set as default
+ EmailScenario.SetDefaultFileAccount(SecondAccount);
+
+ // [WHEN] Open the File Accounts page
+ EmailAccountsTestPage.OpenView();
+
+ // [WHEN] Select the default account
+ BindSubscription(EmailAccountsSelectionMock);
+ EmailAccountsSelectionMock.SelectAccount(SecondAccount."Account Id");
+
+ // [WHEN] Delete action is invoked and the action is confirmed (see ConfirmYesHandler)
+ AccountToSelect := ThirdAccountId; // The third account is selected as the new default account
+ EmailAccountsTestPage.Delete.Invoke();
+
+ // [THEN] The default account was deleted and there is no new default account
+ Assert.IsTrue(EmailAccountsTestPage.GoToKey(FirstAccountId, Enum::"File System Connector"::"Test File System Connector"), 'The first File account should be on the page');
+ Assert.IsFalse(GetDefaultFieldValueAsBoolean(EmailAccountsTestPage.DefaultField.Value), 'The third account should not be marked as default');
+
+ Assert.IsFalse(EmailAccountsTestPage.GoToKey(SecondAccount."Account Id", Enum::"File System Connector"::"Test File System Connector"), 'The second File account should not be on the page');
+
+ Assert.IsTrue(EmailAccountsTestPage.GoToKey(ThirdAccountId, Enum::"File System Connector"::"Test File System Connector"), 'The third File account should be on the page');
+ Assert.IsFalse(GetDefaultFieldValueAsBoolean(EmailAccountsTestPage.DefaultField.Value), 'The third account should not be marked as default');
+ end;
+
+ [Test]
+ [HandlerFunctions('ConfirmYesHandler,ChooseNewDefaultAccountHandler')]
+ procedure DeleteDefaultAccountPromptNewAccountTest()
+ var
+ SecondAccount: Record "File Account";
+ ConnectorMock: Codeunit "Connector Mock";
+ EmailAccountsSelectionMock: Codeunit "File System Acc Selection Mock";
+ EmailScenario: Codeunit "File Scenario";
+ FirstAccountId, ThirdAccountId : Guid;
+ EmailAccountsTestPage: TestPage "File Accounts";
+ begin
+ // [SCENARIO] When the default account is deleted, the user is prompted to choose a new default account
+ PermissionsMock.Set('Email Admin');
+
+ // [GIVEN] A connector is installed and three account are added
+ ConnectorMock.Initialize();
+ ConnectorMock.AddAccount(FirstAccountId);
+ ConnectorMock.AddAccount(SecondAccount);
+ ConnectorMock.AddAccount(ThirdAccountId);
+
+ // [GIVEN] The second account is set as default
+ EmailScenario.SetDefaultFileAccount(SecondAccount);
+
+ // [WHEN] Open the File Accounts page
+ EmailAccountsTestPage.OpenView();
+
+ // [WHEN] Select the default account
+ BindSubscription(EmailAccountsSelectionMock);
+ EmailAccountsSelectionMock.SelectAccount(SecondAccount."Account Id");
+
+ // [WHEN] Delete action is invoked and the action is confirmed (see ConfirmYesHandler)
+ AccountToSelect := ThirdAccountId; // The third account is selected as the new default account
+ EmailAccountsTestPage.Delete.Invoke();
+
+ // [THEN] The second account is not on the page, the third account is set as default
+ Assert.IsTrue(EmailAccountsTestPage.GoToKey(FirstAccountId, Enum::"File System Connector"::"Test File System Connector"), 'The first File account should be on the page');
+ Assert.IsFalse(GetDefaultFieldValueAsBoolean(EmailAccountsTestPage.DefaultField.Value), 'The first account should not be marked as default');
+
+ Assert.IsFalse(EmailAccountsTestPage.GoToKey(SecondAccount."Account Id", Enum::"File System Connector"::"Test File System Connector"), 'The second File account should not be on the page');
+
+ Assert.IsTrue(EmailAccountsTestPage.GoToKey(ThirdAccountId, Enum::"File System Connector"::"Test File System Connector"), 'The third File account should be on the page');
+ Assert.IsTrue(GetDefaultFieldValueAsBoolean(EmailAccountsTestPage.DefaultField.Value), 'The third account should be marked as default');
+ end;
+
+ [Test]
+ procedure DeleteAllAccountsWithoutUITest()
+ var
+ TempEmailAccount: Record "File Account" temporary;
+ TempEmailAccountToDelete: Record "File Account" temporary;
+ ConnectorMock: Codeunit "Connector Mock";
+ EmailAccount: Codeunit "File Account";
+ FirstAccountId, SecondAccountId : Guid;
+ begin
+ // [SCENARIO] When all accounts are deleted, the File Accounts page is empty
+ PermissionsMock.Set('Email Admin');
+
+ // [GIVEN] A connector is installed and two account are added
+ ConnectorMock.Initialize();
+ ConnectorMock.AddAccount(FirstAccountId);
+ ConnectorMock.AddAccount(SecondAccountId);
+
+ // [GIVEN] Mark first account for deletion
+ EmailAccount.GetAllAccounts(TempEmailAccountToDelete);
+ Assert.AreEqual(2, TempEmailAccountToDelete.Count(), 'Expected to have 2 accounts.');
+ TempEmailAccountToDelete.SetRange("Account Id", FirstAccountId);
+
+ // [WHEN] File Accounts are deleted
+ EmailAccount.DeleteAccounts(TempEmailAccountToDelete, true);
+
+ // [THEN] Verify second account still exists
+ EmailAccount.GetAllAccounts(TempEmailAccount);
+ Assert.AreEqual(1, TempEmailAccount.Count(), 'Expected to have 1 account.');
+ TempEmailAccount.FindFirst();
+ Assert.AreEqual(SecondAccountId, TempEmailAccount."Account Id", 'The second File account should still exist.');
+ end;
+
+ [ModalPageHandler]
+ procedure AddAccountModalPageHandler(var AccountWizardTestPage: TestPage "File Account Wizard")
+ begin
+
+ end;
+
+ [PageHandler]
+ procedure SentEmailsPageHandler(var SentEmailsPage: TestPage "Sent Emails")
+ begin
+
+ end;
+
+ [ModalPageHandler]
+ procedure ChooseNewDefaultAccountCancelHandler(var AccountsPage: TestPage "File Accounts")
+ begin
+ AccountsPage.Cancel().Invoke();
+ end;
+
+
+ [ModalPageHandler]
+ procedure ChooseNewDefaultAccountHandler(var AccountsPage: TestPage "File Accounts")
+ begin
+ AccountsPage.GoToKey(AccountToSelect, Enum::"File System Connector"::"Test File System Connector");
+ AccountsPage.OK().Invoke();
+ end;
+
+ [ConfirmHandler]
+ procedure ConfirmYesHandler(Question: Text[1024]; var Reply: Boolean)
+ begin
+ Reply := true;
+ end;
+
+ [ConfirmHandler]
+ procedure ConfirmNoHandler(Question: Text[1024]; var Reply: Boolean)
+ begin
+ Reply := false;
+ end;
+
+ local procedure GetDefaultFieldValueAsBoolean(DefaultFieldValue: Text): Boolean
+ begin
+ exit(DefaultFieldValue = '✓');
+ end;
+}
diff --git a/src/System Application/Test/File System/src/FileScenarioPageTest.Codeunit.al b/src/System Application/Test/File System/src/FileScenarioPageTest.Codeunit.al
new file mode 100644
index 0000000000..c38af682b1
--- /dev/null
+++ b/src/System Application/Test/File System/src/FileScenarioPageTest.Codeunit.al
@@ -0,0 +1,208 @@
+// ------------------------------------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License. See License.txt in the project root for license information.
+// ------------------------------------------------------------------------------------------------
+
+namespace System.Test.FileSystem;
+
+using System.TestLibraries.FileSystem;
+using System.FileSystem;
+using System.TestLibraries.Utilities;
+using System.TestLibraries.Security.AccessControl;
+
+codeunit 134695 "File Scenario Page Test"
+{
+ Subtype = Test;
+
+ var
+ Assert: Codeunit "Library Assert";
+ ConnectorMock: Codeunit "Connector Mock";
+ EmailScenarioMock: Codeunit "File Scenario Mock";
+ PermissionsMock: Codeunit "Permissions Mock";
+ DisplayNameTxt: Label '%1', Locked = true;
+
+
+ [Test]
+ [Scope('OnPrem')]
+ [TransactionModel(TransactionModel::AutoRollback)]
+ procedure PageOpenNoData()
+ var
+ FileScenarioPage: TestPage "File Scenario Setup";
+ begin
+ // [Scenario] The "Email Scenario Setup" shows no data when there are no email accounts
+ PermissionsMock.Set('Email Admin');
+
+ // [Given] No email account is registered.
+ ConnectorMock.Initialize();
+
+ // [When] Opening the the page
+ FileScenarioPage.Trap();
+ FileScenarioPage.OpenView();
+
+ // [Then] There is no data on the page
+ Assert.IsFalse(FileScenarioPage.First(), 'There should be no data on the page');
+ end;
+
+ [Test]
+ [Scope('OnPrem')]
+ [TransactionModel(TransactionModel::AutoRollback)]
+ procedure PageOpenOneEntryTest()
+ var
+ FileAccount: Record "File Account";
+ FileScenarioPage: TestPage "File Scenario Setup";
+ begin
+ // [Scenario] The "Email Scenario Setup" shows one entry when there is only one email account and no scenarios
+ PermissionsMock.Set('File Admin');
+
+ // [Given] One email account is registered.
+ ConnectorMock.Initialize();
+ ConnectorMock.AddAccount(FileAccount);
+
+ // [When] Opening the the page
+ FileScenarioPage.Trap();
+ FileScenarioPage.OpenView();
+
+ // [Then] There is one entry on the page and it is not set as default
+ Assert.IsTrue(FileScenarioPage.First(), 'There should be an entry on the page');
+
+ // Properties are as expected
+ Assert.AreEqual(StrSubstNo(DisplayNameTxt, FileAccount.Name), FileScenarioPage.Name.Value, 'Wrong entry name');
+ Assert.IsFalse(GetDefaultFieldValueAsBoolean(FileScenarioPage.Default.Value), 'The account should not be marked as default');
+
+ // Actions visibility is as expected
+ Assert.IsTrue(FileScenarioPage.AddScenario.Visible(), 'The action "Add Scenarios" should be visible');
+ Assert.IsFalse(FileScenarioPage.ChangeAccount.Visible(), 'The action "Change Accounts" should not be visible');
+ Assert.IsFalse(FileScenarioPage.Unassign.Visible(), 'The action "Unassign" should not be visible');
+
+ Assert.IsFalse(FileScenarioPage.Next(), 'There should not be another entry on the page');
+ end;
+
+ [Test]
+ [Scope('OnPrem')]
+ procedure PageOpenOneDefaultEntryTest()
+ var
+ EmailAccount: Record "File Account";
+ EmailScenarioPage: TestPage "File Scenario Setup";
+ begin
+ // [Scenario] The "Email Scenario Setup" shows one entry when there is only one email account and no scenarios
+ PermissionsMock.Set('File Admin');
+
+ // [Given] One email account is registered and it's set as default.
+ ConnectorMock.Initialize();
+ ConnectorMock.AddAccount(EmailAccount);
+
+ EmailScenarioMock.DeleteAllMappings();
+ EmailScenarioMock.AddMapping(Enum::"File Scenario"::Default, EmailAccount."Account Id", EmailAccount.Connector);
+
+ // [When] Opening the the page
+ EmailScenarioPage.Trap();
+ EmailScenarioPage.OpenView();
+
+ // [Then] There is one entry on the page and it is set as default
+ Assert.IsTrue(EmailScenarioPage.First(), 'There should be an entry on the page');
+
+ // Properties are as expected
+ Assert.AreEqual(StrSubstNo(DisplayNameTxt, EmailAccount.Name), EmailScenarioPage.Name.Value, 'Wrong entry name');
+ Assert.IsTrue(GetDefaultFieldValueAsBoolean(EmailScenarioPage.Default.Value), 'The account should be marked as default');
+
+ // Actions visibility is as expected
+ Assert.IsTrue(EmailScenarioPage.AddScenario.Visible(), 'The action "Add Scenarios" should be visible');
+ Assert.IsFalse(EmailScenarioPage.ChangeAccount.Visible(), 'The action "Change Accounts" should not be visible');
+ Assert.IsFalse(EmailScenarioPage.Unassign.Visible(), 'The action "Unassign" should not be visible');
+
+ Assert.IsFalse(EmailScenarioPage.Next(), 'There should not be another entry on the page');
+ end;
+
+
+ [Test]
+ [Scope('OnPrem')]
+ [TransactionModel(TransactionModel::AutoRollback)]
+ procedure PageOpenOneAcountsTwoScenariosTest()
+ var
+ EmailAccount: Record "File Account";
+ EmailScenarioPage: TestPage "File Scenario Setup";
+ begin
+ // [Scenario] Having one default account with a non-default scenario assigned displays propely on "Email Scenario Setup"
+ PermissionsMock.Set('Email Admin');
+
+ // [Given] One email account is registered and it's set as default.
+ ConnectorMock.Initialize();
+ ConnectorMock.AddAccount(EmailAccount);
+
+ EmailScenarioMock.DeleteAllMappings();
+ EmailScenarioMock.AddMapping(Enum::"File Scenario"::Default, EmailAccount."Account Id", EmailAccount.Connector);
+ EmailScenarioMock.AddMapping(Enum::"File Scenario"::"Test File Scenario", EmailAccount."Account Id", EmailAccount.Connector);
+
+ // [When] Opening the the page
+ EmailScenarioPage.Trap();
+ EmailScenarioPage.OpenView();
+
+ // [Then] There is one entry on the page and it is set as default. There's another entry for the other assigned scenario
+ Assert.IsTrue(EmailScenarioPage.First(), 'There should be data on the page');
+
+ // Properties are as expected
+ Assert.AreEqual(StrSubstNo(DisplayNameTxt, EmailAccount.Name), EmailScenarioPage.Name.Value, 'Wrong entry name');
+ Assert.IsTrue(GetDefaultFieldValueAsBoolean(EmailScenarioPage.Default.Value), 'The account should be marked as default');
+
+ // Actions visibility is as expected
+ Assert.IsTrue(EmailScenarioPage.AddScenario.Visible(), 'The action "Add Scenarios" should be visible');
+ Assert.IsFalse(EmailScenarioPage.ChangeAccount.Visible(), 'The action "Change Accounts" should not be visible');
+ Assert.IsFalse(EmailScenarioPage.Unassign.Visible(), 'The action "Unassign" should not be visible');
+
+ EmailScenarioPage.Expand(true);
+ Assert.IsTrue(EmailScenarioPage.Next(), 'There should be another entry on the page');
+
+ // Properies are as expected
+ Assert.AreEqual(Format(Enum::"File Scenario"::"Test File Scenario"), EmailScenarioPage.Name.Value, 'Wrong entry name');
+ Assert.IsFalse(GetDefaultFieldValueAsBoolean(EmailScenarioPage.Default.Value), 'The account should not be marked as default');
+
+ // Actions visibility is as expected
+ Assert.IsFalse(EmailScenarioPage.AddScenario.Visible(), 'The action "Add Scenarios" should be visible');
+ Assert.IsTrue(EmailScenarioPage.ChangeAccount.Visible(), 'The action "Change Accounts" should not be visible');
+ Assert.IsTrue(EmailScenarioPage.Unassign.Visible(), 'The action "Unassign" should not be visible');
+ end;
+
+ [Test]
+ [Scope('OnPrem')]
+ [TransactionModel(TransactionModel::AutoRollback)]
+ procedure PageOpenTwoAcountsTwoScenariosTest()
+ var
+ FirstEmailAccount, SecondEmailAccount : Record "File Account";
+ EmailScenarioPage: TestPage "File Scenario Setup";
+ begin
+ // [Scenario] The "Email Scenario Setup" shows three entries when there are two accounts - one with the default scenario and one with a non-default scenario
+ PermissionsMock.Set('Email Admin');
+
+ // [Given] Two email accounts are registered. One is set as default.
+ ConnectorMock.Initialize();
+ ConnectorMock.AddAccount(FirstEmailAccount);
+ ConnectorMock.AddAccount(SecondEmailAccount);
+
+ EmailScenarioMock.DeleteAllMappings();
+ EmailScenarioMock.AddMapping(Enum::"File Scenario"::Default, FirstEmailAccount."Account Id", FirstEmailAccount.Connector);
+ EmailScenarioMock.AddMapping(Enum::"File Scenario"::"Test File Scenario", SecondEmailAccount."Account Id", SecondEmailAccount.Connector);
+
+ // [When] Opening the the page
+ EmailScenarioPage.Trap();
+ EmailScenarioPage.OpenView();
+
+ // [Then] There are three entries on the page. One is set as dedault
+ Assert.IsTrue(EmailScenarioPage.GoToKey(-1, FirstEmailAccount."Account Id", FirstEmailAccount.Connector), 'There should be data on the page');
+ Assert.AreEqual(StrSubstNo(DisplayNameTxt, FirstEmailAccount.Name), EmailScenarioPage.Name.Value, 'Wrong first entry name');
+ Assert.IsTrue(GetDefaultFieldValueAsBoolean(EmailScenarioPage.Default.Value), 'The account should be marked as default');
+
+ Assert.IsTrue(EmailScenarioPage.GoToKey(-1, SecondEmailAccount."Account Id", SecondEmailAccount.Connector), 'There should be another entry on the page');
+ Assert.AreEqual(StrSubstNo(DisplayNameTxt, SecondEmailAccount.Name), EmailScenarioPage.Name.Value, 'Wrong second entry name');
+ Assert.IsFalse(GetDefaultFieldValueAsBoolean(EmailScenarioPage.Default.Value), 'The account should not be marked as default');
+
+ EmailScenarioPage.Expand(true);
+ Assert.IsTrue(EmailScenarioPage.Next(), 'There should be a third entry on the page');
+ Assert.AreEqual(Format(Enum::"File Scenario"::"Test File Scenario"), EmailScenarioPage.Name.Value, 'Wrong third entry name');
+ Assert.IsFalse(GetDefaultFieldValueAsBoolean(EmailScenarioPage.Default.Value), 'The account should not be marked as default');
+ end;
+
+ local procedure GetDefaultFieldValueAsBoolean(DefaultFieldValue: Text): Boolean
+ begin
+ exit(DefaultFieldValue = '✓');
+ end;
+}
\ No newline at end of file
diff --git a/src/System Application/Test/File System/src/FileScenarioTest.Codeunit.al b/src/System Application/Test/File System/src/FileScenarioTest.Codeunit.al
new file mode 100644
index 0000000000..7a07468254
--- /dev/null
+++ b/src/System Application/Test/File System/src/FileScenarioTest.Codeunit.al
@@ -0,0 +1,285 @@
+// ------------------------------------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License. See License.txt in the project root for license information.
+// ------------------------------------------------------------------------------------------------
+
+namespace System.Test.FileSystem;
+
+using System.FileSystem;
+using System.TestLibraries.FileSystem;
+using System.TestLibraries.Utilities;
+using System.TestLibraries.Security.AccessControl;
+
+codeunit 134693 "File Scenario Test"
+{
+ Subtype = Test;
+ Permissions = tabledata "File Scenario" = r;
+
+ var
+ Assert: Codeunit "Library Assert";
+ Any: Codeunit Any;
+ ConnectorMock: Codeunit "Connector Mock";
+ FileScenarioMock: Codeunit "File Scenario Mock";
+ FileScenario: Codeunit "File Scenario";
+ PermissionsMock: Codeunit "Permissions Mock";
+
+ [Test]
+ [Scope('OnPrem')]
+ procedure GetFileAccountScenarioNotExistsTest()
+ var
+ FileAccount: Record "File Account";
+ begin
+ // [Scenario] When the File scenario isn't mapped an File account, GetFileAccount returns false
+ PermissionsMock.Set('File Admin');
+
+ // [Given] No mappings between Files and scenarios
+ Initialize();
+
+ // [When] calling GetFileAccount
+ // [Then] false is retuned
+ Assert.IsFalse(FileScenario.GetFileAccount(Enum::"File Scenario"::"Test File Scenario", FileAccount), 'There should not be any account');
+ end;
+
+ [Test]
+ [Scope('OnPrem')]
+ procedure GetFileAccountNotExistsTest()
+ var
+ FileAccount: Record "File Account";
+ NonExistentAccountId: Guid;
+ begin
+ // [Scenario] When the File scenario is mapped non-existing File account, GetFileAccount returns false
+ PermissionsMock.Set('File Admin');
+
+ // [Given] An File scenario pointing to a non-existing File account
+ Initialize();
+ NonExistentAccountId := Any.GuidValue();
+ FileScenarioMock.AddMapping(Enum::"File Scenario"::"Test File Scenario", NonExistentAccountId, Enum::"File System Connector"::"Test File System Connector");
+
+ // [When] calling GetFileAccount
+ // [Then] false is retuned
+ Assert.IsFalse(FileScenario.GetFileAccount(Enum::"File Scenario"::"Test File Scenario", FileAccount), 'There should not be any account mapped to the scenario');
+ end;
+
+ [Test]
+ [Scope('OnPrem')]
+ procedure GetFileAccountDefaultNotExistsTest()
+ var
+ FileAccount: Record "File Account";
+ NonExistentAccountId: Guid;
+ begin
+ // [Scenario] When the default File scenario is mapped to a non-existing File account, GetFileAccount returns false
+ PermissionsMock.Set('File Admin');
+
+ // [Given] An File scenario isn't mapped to a account and the default scenario is mapped to a non-existing account
+ Initialize();
+ NonExistentAccountId := Any.GuidValue();
+ FileScenarioMock.AddMapping(Enum::"File Scenario"::Default, NonExistentAccountId, Enum::"File System Connector"::"Test File System Connector");
+
+ // [When] calling GetFileAccount
+ // [Then] false is retuned
+ Assert.IsFalse(FileScenario.GetFileAccount(Enum::"File Scenario"::"Test File Scenario", FileAccount), 'There should not be any account mapped to the scenario');
+ end;
+
+ [Test]
+ [Scope('OnPrem')]
+ procedure GetFileAccountDefaultExistsTest()
+ var
+ FileAccount: Record "File Account";
+ AccountId: Guid;
+ begin
+ // [Scenario] When the default File scenario is mapped to an existing File account, GetFileAccount returns that account
+ PermissionsMock.Set('File Admin');
+
+ // [Given] An File scenario isn't mapped to an account and the default scenario is mapped to an existing account
+ Initialize();
+ ConnectorMock.AddAccount(AccountId);
+ FileScenarioMock.AddMapping(Enum::"File Scenario"::Default, AccountId, Enum::"File System Connector"::"Test File System Connector");
+
+ // [When] calling GetFileAccount
+ // [Then] true is retuned and the File account is as expected
+ Assert.IsTrue(FileScenario.GetFileAccount(Enum::"File Scenario"::"Test File Scenario", FileAccount), 'There should be an File account');
+ Assert.AreEqual(AccountId, FileAccount."Account Id", 'Wrong account ID');
+ Assert.AreEqual(Enum::"File System Connector"::"Test File System Connector", FileAccount.Connector, 'Wrong connector');
+ end;
+
+ [Test]
+ [Scope('OnPrem')]
+ procedure GetFileAccountExistsTest()
+ var
+ FileAccount: Record "File Account";
+ AccountId: Guid;
+ begin
+ // [Scenario] When the File scenario is mapped to an existing File account, GetFileAccount returns that account
+ PermissionsMock.Set('File Admin');
+
+ // [Given] An File scenario is mapped to an account
+ Initialize();
+ ConnectorMock.AddAccount(AccountId);
+ FileScenarioMock.AddMapping(Enum::"File Scenario"::"Test File Scenario", AccountId, Enum::"File System Connector"::"Test File System Connector");
+
+ // [When] calling GetFileAccount
+ // [Then] true is retuned and the File account is as expected
+ Assert.IsTrue(FileScenario.GetFileAccount(Enum::"File Scenario"::"Test File Scenario", FileAccount), 'There should be an File account');
+ Assert.AreEqual(AccountId, FileAccount."Account Id", 'Wrong account ID');
+ Assert.AreEqual(Enum::"File System Connector"::"Test File System Connector", FileAccount.Connector, 'Wrong connector');
+ end;
+
+ [Test]
+ [Scope('OnPrem')]
+ procedure GetFileAccountDefaultDifferentTest()
+ var
+ FileAccount: Record "File Account";
+ AccountId: Guid;
+ DefaultAccountId: Guid;
+ begin
+ // [Scenario] When the File scenario and the default scenarion are mapped to different File accounts, GetFileAccount returns the corrent account
+ PermissionsMock.Set('File Admin');
+
+ // [Given] An File scenario is mapped to an account, the default scenarion is mapped to another account
+ Initialize();
+ ConnectorMock.AddAccount(AccountId);
+ ConnectorMock.AddAccount(DefaultAccountId);
+ FileScenarioMock.AddMapping(Enum::"File Scenario"::"Test File Scenario", AccountId, Enum::"File System Connector"::"Test File System Connector");
+ FileScenarioMock.AddMapping(Enum::"File Scenario"::Default, DefaultAccountId, Enum::"File System Connector"::"Test File System Connector");
+
+ // [When] calling GetFileAccount
+ // [Then] true is retuned and the File accounts are as expected
+ Assert.IsTrue(FileScenario.GetFileAccount(Enum::"File Scenario"::"Test File Scenario", FileAccount), 'There should be an File account');
+ Assert.AreEqual(AccountId, FileAccount."Account Id", 'Wrong account ID');
+ Assert.AreEqual(Enum::"File System Connector"::"Test File System Connector", FileAccount.Connector, 'Wrong connector');
+
+ Assert.IsTrue(FileScenario.GetFileAccount(Enum::"File Scenario"::Default, FileAccount), 'There should be an File account');
+ Assert.AreEqual(DefaultAccountId, FileAccount."Account Id", 'Wrong account ID');
+ Assert.AreEqual(Enum::"File System Connector"::"Test File System Connector", FileAccount.Connector, 'Wrong connector');
+ end;
+
+ [Test]
+ [Scope('OnPrem')]
+ procedure GetFileAccountDefaultDifferentNotExistTest()
+ var
+ FileAccount: Record "File Account";
+ NonExistingAccountId: Guid;
+ DefaultAccountId: Guid;
+ begin
+ // [Scenario] When the File scenario is mapped to a non-existing account and the default scenarion is mapped to an existing accounts, GetFileAccount returns the corrent account
+ PermissionsMock.Set('File Admin');
+
+ // [Given] An File scenario is mapped to a non-exisitng account, the default scenarion is mapped to an existing account
+ Initialize();
+ ConnectorMock.AddAccount(DefaultAccountId);
+ NonExistingAccountId := Any.GuidValue();
+ FileScenarioMock.AddMapping(Enum::"File Scenario"::"Test File Scenario", NonExistingAccountId, Enum::"File System Connector"::"Test File System Connector");
+ FileScenarioMock.AddMapping(Enum::"File Scenario"::Default, DefaultAccountId, Enum::"File System Connector"::"Test File System Connector");
+
+ // [When] calling GetFileAccount
+ // [Then] true is retuned and the File accounts are as expected
+ Assert.IsTrue(FileScenario.GetFileAccount(Enum::"File Scenario"::"Test File Scenario", FileAccount), 'There should be an File account');
+ Assert.AreEqual(DefaultAccountId, FileAccount."Account Id", 'Wrong account ID');
+ Assert.AreEqual(Enum::"File System Connector"::"Test File System Connector", FileAccount.Connector, 'Wrong connector');
+
+ Assert.IsTrue(FileScenario.GetFileAccount(Enum::"File Scenario"::Default, FileAccount), 'There should be an File account for the default scenario');
+ Assert.AreEqual(DefaultAccountId, FileAccount."Account Id", 'Wrong default account ID');
+ Assert.AreEqual(Enum::"File System Connector"::"Test File System Connector", FileAccount.Connector, 'Wrong default account connector');
+ end;
+
+ [Test]
+ [Scope('OnPrem')]
+ procedure GetFileAccountDifferentDefaultNotExistTest()
+ var
+ FileAccount: Record "File Account";
+ AccountId: Guid;
+ DefaultAccountId: Guid;
+ begin
+ // [Scenario] When the File scenario is mapped to an existing account and the default scenarion is mapped to a non-existing accounts, GetFileAccount returns the corrent account
+ PermissionsMock.Set('File Admin');
+
+ // [Given] An File scenario is mapped to an exisitng account, the default scenarion is mapped to a non-existing account
+ Initialize();
+ ConnectorMock.AddAccount(AccountId);
+ DefaultAccountId := Any.GuidValue();
+ FileScenarioMock.AddMapping(Enum::"File Scenario"::"Test File Scenario", AccountId, Enum::"File System Connector"::"Test File System Connector");
+ FileScenarioMock.AddMapping(Enum::"File Scenario"::Default, DefaultAccountId, Enum::"File System Connector"::"Test File System Connector");
+
+ // [When] calling GetFileAccount
+ // [Then] true is retuned and the File account is as expected
+ Assert.IsTrue(FileScenario.GetFileAccount(Enum::"File Scenario"::"Test File Scenario", FileAccount), 'There should be an File account');
+ Assert.AreEqual(AccountId, FileAccount."Account Id", 'Wrong account ID');
+ Assert.AreEqual(Enum::"File System Connector"::"Test File System Connector", FileAccount.Connector, 'Wrong connector');
+
+ // [Then] there's no account for the default File scenario
+ Assert.IsFalse(FileScenario.GetFileAccount(Enum::"File Scenario"::Default, FileAccount), 'There should not be an File account for the default scenario');
+ end;
+
+ [Test]
+ [Scope('OnPrem')]
+ procedure SetFileAccountTest()
+ var
+ FileAccount: Record "File Account";
+ AnotherAccount: Record "File Account";
+ FileScenarios: Record "File Scenario";
+ Scenario: Enum "File Scenario";
+ begin
+ // [Scenario] When SetAccount is called, the entry in the database is as expected
+ PermissionsMock.Set('File Admin');
+
+ // [Given] A random File account
+ Initialize();
+ FileAccount."Account Id" := Any.GuidValue();
+ FileAccount.Connector := Enum::"File System Connector"::"Test File System Connector";
+ Scenario := Scenario::Default;
+
+ // [When] Setting the File account for the scenario
+ FileScenario.SetFileAccount(Scenario, FileAccount);
+
+ // [Then] The scenario exists and is as expected
+ Assert.IsTrue(FileScenarios.Get(Scenario), 'The File scenario should exist');
+ Assert.AreEqual(FileScenarios."Account Id", FileAccount."Account Id", 'Wrong accound ID');
+ Assert.AreEqual(FileScenarios.Connector, FileAccount.Connector, 'Wrong connector');
+
+ AnotherAccount."Account Id" := Any.GuidValue();
+ AnotherAccount.Connector := Enum::"File System Connector"::"Test File System Connector";
+
+ // [When] Setting overwting the File account for the scenario
+ FileScenario.SetFileAccount(Scenario, AnotherAccount);
+
+ // [Then] The scenario still exists and is as expected
+ Assert.IsTrue(FileScenarios.Get(Scenario), 'The File scenario should exist');
+ Assert.AreEqual(FileScenarios."Account Id", AnotherAccount."Account Id", 'Wrong accound ID');
+ Assert.AreEqual(FileScenarios.Connector, AnotherAccount.Connector, 'Wrong connector');
+ end;
+
+ [Test]
+ [Scope('OnPrem')]
+ procedure UnassignScenarioTest()
+ var
+ FileAccount: Record "File Account";
+ DefaultAccount: Record "File Account";
+ ResultAccount: Record "File Account";
+ begin
+ // [Scenario] When unassigning a scenario then it falls back to the default account.
+ PermissionsMock.Set('File Admin');
+
+ // [Given] Two accounts, one default and one not
+ Initialize();
+ ConnectorMock.AddAccount(FileAccount);
+ ConnectorMock.AddAccount(DefaultAccount);
+ FileScenario.SetDefaultFileAccount(DefaultAccount);
+ FileScenario.SetFileAccount(Enum::"File Scenario"::"Test File Scenario", FileAccount);
+
+ // mid-test verification
+ FileScenario.GetFileAccount(Enum::"File Scenario"::"Test File Scenario", ResultAccount);
+ Assert.AreEqual(FileAccount."Account Id", ResultAccount."Account Id", 'Wrong account');
+
+ // [When] Unassign the File scenario
+ FileScenario.UnassignScenario(Enum::"File Scenario"::"Test File Scenario");
+
+ // [Then] The default account is returned for that account
+ FileScenario.GetFileAccount(Enum::"File Scenario"::"Test File Scenario", ResultAccount);
+ Assert.AreEqual(DefaultAccount."Account Id", ResultAccount."Account Id", 'The default account should have been returned');
+ end;
+
+ local procedure Initialize()
+ begin
+ FileScenarioMock.DeleteAllMappings();
+ end;
+}
\ No newline at end of file
diff --git a/src/System Application/Test/File System/src/FileSystemlTest.Codeunit.al b/src/System Application/Test/File System/src/FileSystemlTest.Codeunit.al
new file mode 100644
index 0000000000..3ad8dcdc70
--- /dev/null
+++ b/src/System Application/Test/File System/src/FileSystemlTest.Codeunit.al
@@ -0,0 +1,1552 @@
+// ------------------------------------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License. See License.txt in the project root for license information.
+// ------------------------------------------------------------------------------------------------
+
+namespace System.Test.FileSystem;
+
+using System.FileSystem;
+using System.Text;
+using System.TestLibraries.FileSystem;
+using System.Environment;
+using System.TestLibraries.Reflection;
+using System.TestLibraries.Utilities;
+using System.TestLibraries.Security.AccessControl;
+
+codeunit 134685 "File System Test"
+{
+ Subtype = Test;
+ Permissions = tabledata "Email Message" = rd,
+ tabledata "Email Message Attachment" = rd,
+ tabledata "Email Recipient" = rd,
+ tabledata "Email Outbox" = rimd,
+ tabledata "Scheduled Task" = rd,
+ tabledata "Sent Email" = rid;
+
+ EventSubscriberInstance = Manual;
+
+ var
+ Assert: Codeunit "Library Assert";
+ Email: Codeunit Email;
+ Base64Convert: Codeunit "Base64 Convert";
+ PermissionsMock: Codeunit "Permissions Mock";
+ EmailMessageDoesNotExistMsg: Label 'The email message has been deleted by another user.', Locked = true;
+ EmailMessageOpenPermissionErr: Label 'You do not have permission to open the email message.';
+ EmailMessageCannotBeEditedErr: Label 'The email message has already been sent and cannot be edited.';
+ EmailMessageQueuedCannotDeleteAttachmentErr: Label 'Cannot delete the attachment because the email has been queued to be sent.';
+ EmailMessageSentCannotDeleteAttachmentErr: Label 'Cannot delete the attachment because the email has already been sent.';
+ AccountNameLbl: Label '%1 (%2)', Locked = true;
+ NoRelatedAttachmentsErr: Label 'Did not find any attachments related to this email.';
+ OutboxSourceTextLbl: Label '%1: %2', Locked = true;
+
+ [Test]
+ [Scope('OnPrem')]
+ [TransactionModel(TransactionModel::AutoRollback)]
+ procedure NonExistingEmailMessageFailsTest()
+ var
+ Message: Record "Email Message";
+ EmailMessage: Codeunit "Email Message";
+ begin
+ // [Scenario] User cannot save as draft, enqueue, send or open (in editor) a non-existing email message
+ PermissionsMock.Set('Email Edit');
+
+ // [Given] Create an Email Message and delete the underlying record
+ CreateEmail(EmailMessage);
+ Assert.IsTrue(Message.Get(EmailMessage.GetId()), 'The record should have been created');
+ Message.Delete();
+
+ Assert.IsFalse(EmailMessage.Get(EmailMessage.GetId()), 'The email should not exist');
+
+ // [When] Saving a non-existing email message as draft
+ ClearLastError();
+ asserterror Email.SaveAsDraft(EmailMessage);
+
+ // [Then] An error occurs
+ Assert.ExpectedError(EmailMessageDoesNotExistMsg);
+
+ // [When] Enqueuing a non-existing email message
+ ClearLastError();
+ asserterror Email.Enqueue(EmailMessage);
+
+ // [Then] An error occurs
+ Assert.ExpectedError(EmailMessageDoesNotExistMsg);
+
+ // [When] Sending a non-existing email message
+ ClearLastError();
+ asserterror Email.Send(EmailMessage);
+
+ // [Then] An error occurs
+ Assert.ExpectedError(EmailMessageDoesNotExistMsg);
+
+ // [When] Opening a non-existing email message
+ ClearLastError();
+ asserterror Email.OpenInEditor(EmailMessage);
+
+ // [Then] An error occurs
+ Assert.ExpectedError(EmailMessageDoesNotExistMsg);
+
+ // [When] Opening a non-existing email message modally
+ ClearLastError();
+ asserterror Email.OpenInEditorModally(EmailMessage);
+
+ // [Then] An error occurs
+ Assert.ExpectedError(EmailMessageDoesNotExistMsg);
+ end;
+
+ [Test]
+ [Scope('OnPrem')]
+ [TransactionModel(TransactionModel::AutoRollback)]
+ procedure SaveAsDraftEmailMessage()
+ var
+ EmailOutbox: Record "Email Outbox";
+ EmailMessage: Codeunit "Email Message";
+ EmptyConnector: Enum "Email Connector";
+ EmptyGuid: Guid;
+ begin
+ // [Scenario] When saving an existing email as draft, it appears in the outbox
+ PermissionsMock.Set('Email Edit');
+
+ // [Given] An email message
+ CreateEmail(EmailMessage);
+ Assert.IsTrue(EmailMessage.Get(EmailMessage.GetId()), 'The email message should exist');
+
+ // [When] Saving the email message as draft
+ ClearLastError();
+ Email.SaveAsDraft(EmailMessage);
+
+ // [Then] No error occurs
+ Assert.AreEqual('', GetLastErrorText(), 'There should be no errors when saving an email.');
+
+ // [Then] The draft email should be correct
+ EmailOutbox.SetRange("Message Id", EmailMessage.GetId());
+ Assert.AreEqual(1, EmailOutbox.Count(), 'There should be only one draft email');
+ Assert.IsTrue(EmailOutbox.FindFirst(), 'The message should be in the outbox');
+
+ Assert.AreEqual(EmptyGuid, EmailOutbox."Account Id", 'The account should not be set');
+ Assert.AreEqual(EmptyConnector, EmailOutbox.Connector, 'The connector should not be set');
+ Assert.AreEqual(EmailOutbox.Status::"Draft", EmailOutbox.Status, 'The status should be ''Draft''');
+ Assert.AreEqual(UserSecurityId(), EmailOutbox."User Security Id", 'The user security ID should be the current user');
+ Assert.AreEqual(EmailMessage.GetSubject(), EmailOutbox.Description, 'The description does not match the email title');
+ Assert.AreEqual('', EmailOutbox."Error Message", 'The error message should be blank');
+ end;
+
+ [Test]
+ [Scope('OnPrem')]
+ [TransactionModel(TransactionModel::AutoRollback)]
+ procedure SaveAsDraftEmailMessageTwice()
+ var
+ EmailOutbox: Record "Email Outbox";
+ EmailMessage: Codeunit "Email Message";
+ EmptyConnector: Enum "Email Connector";
+ EmptyGuid: Guid;
+ begin
+ // [Scenario] When enqueuing an existing email, it appears in the outbox
+ PermissionsMock.Set('Email Edit');
+
+ // [Given] A GUID of an email
+ CreateEmail(EmailMessage);
+ Assert.IsTrue(EmailMessage.Get(EmailMessage.GetId()), 'The email message should exist');
+
+ // [When] Enqueuing the email
+ ClearLastError();
+ Email.SaveAsDraft(EmailMessage);
+
+ // [Then] No error occurs
+ Assert.AreEqual('', GetLastErrorText(), 'There should be no errors when saving the email message.');
+
+ // [Then] The draft email should be the correct one
+ EmailOutbox.SetRange("Message Id", EmailMessage.GetId());
+ Assert.AreEqual(1, EmailOutbox.Count(), 'There should be only one enqueued message');
+ Assert.IsTrue(EmailOutbox.FindFirst(), 'The message should be queued');
+
+ Assert.AreEqual(EmptyGuid, EmailOutbox."Account Id", 'The account should not be set');
+ Assert.AreEqual(EmptyConnector, EmailOutbox.Connector, 'The connector should not be set');
+ Assert.AreEqual(EmailOutbox.Status::"Draft", EmailOutbox.Status, 'The status should be ''Draft''');
+ Assert.AreEqual(UserSecurityId(), EmailOutbox."User Security Id", 'The user security ID should be the current user');
+ Assert.AreEqual(EmailMessage.GetSubject(), EmailOutbox.Description, 'The description does not match the email title');
+ Assert.AreEqual('', EmailOutbox."Error Message", 'The error message should be blank');
+
+ // [When] Saving the email message again
+ ClearLastError();
+ Email.SaveAsDraft(EmailMessage);
+
+ // [Then] No error occurs
+ Assert.AreEqual('', GetLastErrorText(), 'There should be no errors when saving the email message again.');
+
+ // [Then] The draft email should be the correct one
+ EmailOutbox.SetRange("Message Id", EmailMessage.GetId());
+ Assert.AreEqual(1, EmailOutbox.Count(), 'There should be only one draft message');
+ Assert.IsTrue(EmailOutbox.FindFirst(), 'The message should be queued');
+
+ Assert.AreEqual(EmptyGuid, EmailOutbox."Account Id", 'The account should not be set');
+ Assert.AreEqual(EmptyConnector, EmailOutbox.Connector, 'The connector should not be set');
+ Assert.AreEqual(EmailOutbox.Status::"Draft", EmailOutbox.Status, 'The status should be ''Draft''');
+ Assert.AreEqual(UserSecurityId(), EmailOutbox."User Security Id", 'The user security ID should be the current user');
+ Assert.AreEqual(EmailMessage.GetSubject(), EmailOutbox.Description, 'The description does not match the email title');
+ Assert.AreEqual('', EmailOutbox."Error Message", 'The error message should be blank');
+ end;
+
+ [Test]
+ [HandlerFunctions('CloseEmailEditorHandler')]
+ procedure OpenMessageInEditorTest()
+ var
+ TempAccount: Record "Email Account" temporary;
+ EmailMessage: Codeunit "Email Message";
+ ConnectorMock: Codeunit "Connector Mock";
+ EmailEditor: TestPage "Email Editor";
+ Recipients: List of [Text];
+ begin
+ // Initialize
+ ConnectorMock.Initialize();
+ ConnectorMock.AddAccount(TempAccount);
+
+ PermissionsMock.Set('Email Edit');
+
+ Recipients.Add('recipient1@test.com');
+ Recipients.Add('recipient2@test.com');
+ EmailMessage.Create(Recipients, 'Test subject', 'Test body', true);
+ EmailMessage.AddAttachment('Attachment1', 'text/plain', Base64Convert.ToBase64('Content'));
+ EmailMessage.AddAttachment('Attachment1', 'text/plain', Base64Convert.ToBase64('Content'));
+
+ // Exercise
+ EmailEditor.Trap();
+ Email.OpenInEditor(EmailMessage);
+
+ // Verify
+ Assert.AreEqual('', EmailEditor.Account.Value(), 'Account field was not blank.');
+ Assert.AreEqual('recipient1@test.com;recipient2@test.com', EmailEditor.ToField.Value(), 'A different To was expected');
+ Assert.AreEqual('Test subject', EmailEditor.SubjectField.Value(), 'A different subject was expected.');
+ Assert.AreEqual('Test body', EmailEditor.BodyField.Value(), 'A different body was expected.');
+ Assert.AreEqual('', EmailEditor.CcField.Value(), 'Cc field was not blank.');
+ Assert.AreEqual('', EmailEditor.BccField.Value(), 'Bcc field was not blank.');
+
+ Assert.IsTrue(EmailEditor.Attachments.First(), 'First Attachment was not found.');
+ Assert.AreEqual('Attachment1', EmailEditor.Attachments.FileName.Value(), 'A different attachment filename was expected');
+ Assert.IsTrue(EmailEditor.Attachments.Next(), 'Second Attachment was not found.');
+ Assert.AreEqual('Attachment1', EmailEditor.Attachments.FileName.Value(), 'A different attachment filename was expected');
+
+ // Exercise
+ EmailEditor.Trap();
+ Email.OpenInEditor(EmailMessage, TempAccount);
+
+ // Verify
+ Assert.AreEqual(StrSubstNo(AccountNameLbl, TempAccount.Name, TempAccount."Email Address"), EmailEditor.Account.Value(), 'A different account was expected');
+ Assert.AreEqual('recipient1@test.com;recipient2@test.com', EmailEditor.ToField.Value(), 'A different To was expected');
+ Assert.AreEqual('Test subject', EmailEditor.SubjectField.Value(), 'A different subject was expected.');
+ Assert.AreEqual('Test body', EmailEditor.BodyField.Value(), 'A different body was expected.');
+ Assert.AreEqual('', EmailEditor.CcField.Value(), 'Cc field was not blank.');
+ Assert.AreEqual('', EmailEditor.BccField.Value(), 'Bcc field was not blank.');
+
+ Assert.IsTrue(EmailEditor.Attachments.First(), 'First Attachment was not found.');
+ Assert.AreEqual('Attachment1', EmailEditor.Attachments.FileName.Value(), 'A different attachment filename was expected');
+ Assert.IsTrue(EmailEditor.Attachments.Next(), 'Second Attachment was not found.');
+ Assert.AreEqual('Attachment1', EmailEditor.Attachments.FileName.Value(), 'A different attachment filename was expected');
+
+ // Exercise
+ EmailEditor.Trap();
+ Email.OpenInEditor(EmailMessage, TempAccount);
+
+ // Verify
+ Assert.AreEqual(StrSubstNo(AccountNameLbl, TempAccount.Name, TempAccount."Email Address"), EmailEditor.Account.Value(), 'A different account was expected');
+ Assert.AreEqual('recipient1@test.com;recipient2@test.com', EmailEditor.ToField.Value(), 'A different To was expected');
+ Assert.AreEqual('Test subject', EmailEditor.SubjectField.Value(), 'A different subject was expected.');
+ Assert.AreEqual('Test body', EmailEditor.BodyField.Value(), 'A different body was expected.');
+ Assert.AreEqual('', EmailEditor.CcField.Value(), 'Cc field was not blank.');
+ Assert.AreEqual('', EmailEditor.BccField.Value(), 'Bcc field was not blank.');
+
+ Assert.IsTrue(EmailEditor.Attachments.First(), 'First Attachment was not found.');
+ Assert.AreEqual('Attachment1', EmailEditor.Attachments.FileName.Value(), 'A different attachment filename was expected');
+ Assert.IsTrue(EmailEditor.Attachments.Next(), 'Second Attachment was not found.');
+ Assert.AreEqual('Attachment1', EmailEditor.Attachments.FileName.Value(), 'A different attachment filename was expected');
+ end;
+
+ [Test]
+ [TransactionModel(TransactionModel::AutoRollback)]
+ procedure OpenMessageInEditorForAQueuedMessageTest()
+ var
+ TempAccount: Record "Email Account" temporary;
+ EmailOutBox: Record "Email Outbox";
+ EmailMessageAttachment: Record "Email Message Attachment";
+ EmailMessage: Codeunit "Email Message";
+ ConnectorMock: Codeunit "Connector Mock";
+ EmailEditor: TestPage "Email Editor";
+ begin
+ // Initialize
+ ConnectorMock.Initialize();
+ ConnectorMock.AddAccount(TempAccount);
+
+ PermissionsMock.Set('Email Edit');
+
+ CreateEmail(EmailMessage);
+ EmailMessage.AddAttachment('Attachment1', 'text/plain', Base64Convert.ToBase64('Content'));
+ EmailMessage.AddAttachment('Attachment1', 'text/plain', Base64Convert.ToBase64('Content'));
+
+ EmailOutBox.Init();
+ EmailOutBox."Account Id" := TempAccount."Account Id";
+ EmailOutBox.Connector := Enum::"Email Connector"::"Test Email Connector";
+ EmailOutBox."Message Id" := EmailMessage.GetId();
+ EmailOutBox.Status := Enum::"Email Status"::Queued;
+ EmailOutBox."User Security Id" := UserSecurityId();
+ EmailOutBox.Insert();
+
+ // Exercise
+ EmailEditor.Trap();
+ Email.OpenInEditor(EmailMessage);
+
+ // Verify
+ Assert.IsFalse(EmailEditor.Account.Enabled(), 'Account field was enabled');
+ Assert.IsFalse(EmailEditor.ToField.Editable(), 'To field was editable');
+ Assert.IsFalse(EmailEditor.CcField.Editable(), 'Cc field was editable');
+ Assert.IsFalse(EmailEditor.BccField.Editable(), 'Bcc field was editable');
+ Assert.IsFalse(EmailEditor.SubjectField.Editable(), 'Subject field was editable');
+ Assert.IsFalse(EmailEditor.BodyField.Editable(), 'Body field was editable');
+ Assert.IsFalse(EmailEditor.Attachments.Upload.Visible(), 'Upload Action is visible.');
+ Assert.IsFalse(EmailEditor.Send.Enabled(), 'Send Action was not disabled.');
+
+ EmailOutBox.Status := Enum::"Email Status"::Processing;
+ EmailOutBox.Modify();
+
+ // Exercise
+ EmailEditor.Trap();
+ Email.OpenInEditor(EmailMessage);
+
+ // Verify
+ Assert.IsFalse(EmailEditor.Account.Enabled(), 'Account field was enabled');
+ Assert.IsFalse(EmailEditor.ToField.Editable(), 'To field was editable');
+ Assert.IsFalse(EmailEditor.CcField.Editable(), 'Cc field was editable');
+ Assert.IsFalse(EmailEditor.BccField.Editable(), 'Bcc field was editable');
+ Assert.IsFalse(EmailEditor.SubjectField.Editable(), 'Subject field was editable');
+ Assert.IsFalse(EmailEditor.BodyField.Editable(), 'Body field was editable');
+ Assert.IsFalse(EmailEditor.Attachments.Upload.Visible(), 'Upload Action is visible.');
+ Assert.IsFalse(EmailEditor.Send.Enabled(), 'Send Action was not disabled.');
+ EmailMessageAttachment.SetRange("Email Message Id", EmailMessage.GetId());
+ EmailMessageAttachment.FindFirst();
+ asserterror EmailMessageAttachment.Delete();
+ Assert.ExpectedError(EmailMessageQueuedCannotDeleteAttachmentErr);
+ end;
+
+ [Test]
+ [TransactionModel(TransactionModel::AutoRollback)]
+ procedure OpenMessageInEditorForAQueuedMessageOwnedByAnotherUserTest()
+ var
+ TempAccount: Record "Email Account" temporary;
+ EmailOutBox: Record "Email Outbox";
+ EmailMessage: Codeunit "Email Message";
+ ConnectorMock: Codeunit "Connector Mock";
+ EmailEditor: TestPage "Email Editor";
+ begin
+ // Initialize
+ ConnectorMock.Initialize();
+ ConnectorMock.AddAccount(TempAccount);
+
+ PermissionsMock.Set('Email Edit');
+
+ CreateEmail(EmailMessage);
+
+ EmailOutBox.Init();
+ EmailOutBox."Account Id" := TempAccount."Account Id";
+ EmailOutBox.Connector := Enum::"Email Connector"::"Test Email Connector";
+ EmailOutBox."Message Id" := EmailMessage.GetId();
+ EmailOutBox.Status := Enum::"Email Status"::Queued;
+ EmailOutbox."User Security Id" := 'd0a983f4-0fc8-4982-8e02-ee9294ab28da'; // Created by another user
+ EmailOutBox.Insert();
+
+ // Exercise/Verify
+ EmailEditor.Trap();
+ asserterror Email.OpenInEditor(EmailMessage);
+ Assert.ExpectedError(EmailMessageOpenPermissionErr);
+ end;
+
+ [Test]
+ procedure OpenSentMessageInEditorTest()
+ var
+ TempAccount: Record "Email Account" temporary;
+ EmailMessage: Codeunit "Email Message";
+ ConnectorMock: Codeunit "Connector Mock";
+ EmailEditor: TestPage "Email Editor";
+ begin
+ // Initialize
+ ConnectorMock.Initialize();
+ ConnectorMock.AddAccount(TempAccount);
+
+ PermissionsMock.Set('Email Edit');
+
+ CreateEmail(EmailMessage);
+
+ Email.Send(EmailMessage, TempAccount);
+
+ // Exercise/Verify
+ EmailEditor.Trap();
+ asserterror Email.OpenInEditor(EmailMessage);
+ Assert.ExpectedError(EmailMessageCannotBeEditedErr);
+ end;
+
+
+ [Test]
+ [HandlerFunctions('EmailEditorHandler,OnEmailEditorClose')]
+ procedure OpenInEditorModallyDiscardAOptionTest()
+ var
+ TempAccount: Record "Email Account" temporary;
+ EmailOutbox: Record "Email Outbox";
+ SentEmail: Record "Sent Email";
+ Message: Record "Email Message";
+ Attachment: Record "Email Message Attachment";
+ Recipient: Record "Email Recipient";
+ EmailMessage: Codeunit "Email Message";
+ ConnectorMock: Codeunit "Connector Mock";
+ EmailAction: Enum "Email Action";
+ begin
+ // Initialize
+ ConnectorMock.Initialize();
+ ConnectorMock.AddAccount(TempAccount);
+
+ PermissionsMock.Set('Email Edit');
+
+ CreateEmail(EmailMessage);
+ EmailMessage.AddAttachment('Attachment1', 'text/plain', Base64Convert.ToBase64('Content'));
+
+ OptionChoice := 2; // Discard email
+ EmailAction := Email.OpenInEditorModally(EmailMessage, TempAccount);
+
+ // Exercise/Verify
+ // See EmailEditorHandler
+
+ // When the message was discarded, there should be no leftover records
+ Assert.AreEqual(Enum::"Email Action"::Discarded, EmailAction, 'Wrong email action returned');
+
+ Assert.IsFalse(EmailMessage.Get(EmailMessage.GetId()), 'The email message should not exist');
+ Assert.IsFalse(Message.Get(EmailMessage.GetId()), 'The email message record should not exist');
+
+ EmailOutbox.SetRange("Message Id", EmailMessage.GetId());
+ Assert.IsTrue(EmailOutbox.IsEmpty(), 'There should be no outbox to the discarded message');
+
+ SentEmail.SetRange("Message Id", EmailMessage.GetId());
+ Assert.IsTrue(SentEmail.IsEmpty(), 'There should be no sent email to the discarded message');
+
+ Recipient.SetRange("Email Message Id", EmailMessage.GetId());
+ Assert.IsTrue(Recipient.IsEmpty(), 'There should be no recipient to the discarded message');
+
+ Attachment.SetRange("Email Message Id", EmailMessage.GetId());
+ Assert.IsTrue(Attachment.IsEmpty(), 'There should be no attachments to the discarded message');
+ end;
+
+ [Test]
+ [HandlerFunctions('EmailEditorHandler,OnEmailEditorClose')]
+ procedure OpenInEditorModallySaveAsDraftOptionTest()
+ var
+ TempAccount: Record "Email Account" temporary;
+ EmailOutbox: Record "Email Outbox";
+ SentEmail: Record "Sent Email";
+ Message: Record "Email Message";
+ Attachment: Record "Email Message Attachment";
+ Recipient: Record "Email Recipient";
+ EmailMessage: Codeunit "Email Message";
+ ConnectorMock: Codeunit "Connector Mock";
+ EmailAction: Enum "Email Action";
+ begin
+ // Initialize
+ ConnectorMock.Initialize();
+ ConnectorMock.AddAccount(TempAccount);
+
+ PermissionsMock.Set('Email Edit');
+
+ CreateEmail(EmailMessage);
+ EmailMessage.AddAttachment('Attachment1', 'text/plain', Base64Convert.ToBase64('Content'));
+
+ OptionChoice := 1; // Keep as draft
+ EmailAction := Email.OpenInEditorModally(EmailMessage, TempAccount);
+
+ // Exercise/Verify
+ // See EmailEditorHandler
+
+ // Exercise
+ // When the message was saved as draft (see OnEmailEditorClose)
+
+ // Verify
+ Assert.AreEqual(Enum::"Email Action"::"Saved As Draft", EmailAction, 'Wrong email action returned');
+
+ Assert.IsTrue(EmailMessage.Get(EmailMessage.GetId()), 'The email message should exist');
+ Assert.IsTrue(Message.Get(EmailMessage.GetId()), 'The email message record should exist');
+
+ EmailOutbox.SetRange("Message Id", EmailMessage.GetId());
+ Assert.IsFalse(EmailOutbox.IsEmpty(), 'There should be an outbox to the message');
+
+ SentEmail.SetRange("Message Id", EmailMessage.GetId());
+ Assert.IsTrue(SentEmail.IsEmpty(), 'There should be no sent email to the message');
+
+ Recipient.SetRange("Email Message Id", EmailMessage.GetId());
+ Assert.IsFalse(Recipient.IsEmpty(), 'There should be a recipient to the message');
+
+ Attachment.SetRange("Email Message Id", EmailMessage.GetId());
+ Assert.IsFalse(Attachment.IsEmpty(), 'There should be an attachment to the discarded message');
+ end;
+
+ [Test]
+ [HandlerFunctions('SendEmailEditorHandler')]
+ procedure OpenInEditorModallySendActionTest()
+ var
+ TempAccount: Record "Email Account" temporary;
+ EmailOutbox: Record "Email Outbox";
+ SentEmail: Record "Sent Email";
+ Message: Record "Email Message";
+ Attachment: Record "Email Message Attachment";
+ Recipient: Record "Email Recipient";
+ EmailMessage: Codeunit "Email Message";
+ ConnectorMock: Codeunit "Connector Mock";
+ EmailAction: Enum "Email Action";
+ begin
+ // Initialize
+ ConnectorMock.Initialize();
+ ConnectorMock.AddAccount(TempAccount);
+
+ PermissionsMock.Set('Email Edit');
+
+ CreateEmail(EmailMessage);
+ EmailMessage.AddAttachment('Attachment1', 'text/plain', Base64Convert.ToBase64('Content'));
+
+ EmailAction := Email.OpenInEditorModally(EmailMessage, TempAccount);
+
+ // Exercise
+ // See SendEmailEditorHandlers
+
+ // Verify
+ Assert.AreEqual(Enum::"Email Action"::Sent, EmailAction, 'Wrong email action returned');
+
+ Assert.IsTrue(EmailMessage.Get(EmailMessage.GetId()), 'The email message should exist');
+ Assert.IsTrue(Message.Get(EmailMessage.GetId()), 'The email message record should exist');
+
+ EmailOutbox.SetRange("Message Id", EmailMessage.GetId());
+ Assert.IsTrue(EmailOutbox.IsEmpty(), 'There should be no outbox to the message');
+
+ SentEmail.SetRange("Message Id", EmailMessage.GetId());
+ Assert.IsFalse(SentEmail.IsEmpty(), 'There should be a sent email to the message');
+
+ Recipient.SetRange("Email Message Id", EmailMessage.GetId());
+ Assert.IsFalse(Recipient.IsEmpty(), 'There should be a recipient to the message');
+
+ Attachment.SetRange("Email Message Id", EmailMessage.GetId());
+ Assert.IsFalse(Attachment.IsEmpty(), 'There should be an attachment to the discarded message');
+ end;
+
+ [Test]
+ [HandlerFunctions('DiscardEmailEditorHandler,ConfirmYes')]
+ procedure OpenInEditorModallyDiscardActionTest()
+ var
+ TempAccount: Record "Email Account" temporary;
+ EmailOutbox: Record "Email Outbox";
+ SentEmail: Record "Sent Email";
+ Message: Record "Email Message";
+ Attachment: Record "Email Message Attachment";
+ Recipient: Record "Email Recipient";
+ EmailMessage: Codeunit "Email Message";
+ ConnectorMock: Codeunit "Connector Mock";
+ EmailAction: Enum "Email Action";
+ begin
+ // Initialize
+ ConnectorMock.Initialize();
+ ConnectorMock.AddAccount(TempAccount);
+
+ PermissionsMock.Set('Email Edit');
+
+ CreateEmail(EmailMessage);
+ EmailMessage.AddAttachment('Attachment1', 'text/plain', Base64Convert.ToBase64('Content'));
+
+ EmailAction := Email.OpenInEditorModally(EmailMessage, TempAccount);
+
+ // Exercise
+ // See DiscardEmailEditorHandler
+
+ // Verify
+ Assert.AreEqual(Enum::"Email Action"::Discarded, EmailAction, 'Wrong email action returned');
+
+ Assert.IsFalse(EmailMessage.Get(EmailMessage.GetId()), 'The email message should not exist');
+ Assert.IsFalse(Message.Get(EmailMessage.GetId()), 'The email message record should not exist');
+
+ EmailOutbox.SetRange("Message Id", EmailMessage.GetId());
+ Assert.IsTrue(EmailOutbox.IsEmpty(), 'There should be no outbox to the message');
+
+ SentEmail.SetRange("Message Id", EmailMessage.GetId());
+ Assert.IsTrue(SentEmail.IsEmpty(), 'There should be no sent email to the message');
+
+ Recipient.SetRange("Email Message Id", EmailMessage.GetId());
+ Assert.IsTrue(Recipient.IsEmpty(), 'There should be no recipient to the message');
+
+ Attachment.SetRange("Email Message Id", EmailMessage.GetId());
+ Assert.IsTrue(Attachment.IsEmpty(), 'There should be no attachment to the discarded message');
+ end;
+
+ [Test]
+ [Scope('OnPrem')]
+ [TransactionModel(TransactionModel::AutoRollback)]
+ procedure EnqueueExistingEmailTest()
+ var
+ EmailOutbox: Record "Email Outbox";
+ EmailMessage: Codeunit "Email Message";
+ ConnectorMock: Codeunit "Connector Mock";
+ AccountId: Guid;
+ begin
+ // [Scenario] When enqueuing an existing email, it appears in the outbox
+ PermissionsMock.Set('Email Edit');
+
+ // [Given] An email message and an email account
+ CreateEmail(EmailMessage);
+ Assert.IsTrue(EmailMessage.Get(EmailMessage.GetId()), 'The email should exist');
+ ConnectorMock.Initialize();
+ ConnectorMock.AddAccount(AccountId);
+
+ // [When] Enqueuing the email message with the email account
+ ClearLastError();
+ Email.Enqueue(EmailMessage, AccountId, Enum::"Email Connector"::"Test Email Connector");
+
+ // [Then] No error occurs
+ Assert.AreEqual('', GetLastErrorText(), 'There should be no errors when enqueuing an email.');
+
+ // [Then] The enqueued email should be the correct one
+ EmailOutbox.SetRange("Message Id", EmailMessage.GetId());
+ Assert.AreEqual(1, EmailOutbox.Count(), 'There should be only one enqueued message');
+ Assert.IsTrue(EmailOutbox.FindFirst(), 'The message should be queued');
+
+ Assert.AreEqual(AccountId, EmailOutbox."Account Id", 'The account should be set');
+ Assert.AreEqual(Enum::"Email Connector"::"Test Email Connector", EmailOutbox.Connector, 'The connector should be set');
+ Assert.AreEqual(EmailOutbox.Status::Queued, EmailOutbox.Status, 'The status should be ''Queued''');
+ Assert.AreEqual(UserSecurityId(), EmailOutbox."User Security Id", 'The user security ID should be the current user');
+ Assert.AreEqual(EmailMessage.GetSubject(), EmailOutbox.Description, 'The description does not match the email title');
+ Assert.AreEqual('', EmailOutbox."Error Message", 'The error message should be blank');
+ end;
+
+ [Test]
+ [Scope('OnPrem')]
+ [TransactionModel(TransactionModel::AutoRollback)]
+ procedure EnqueueScheduledEmailTest()
+ var
+ EmailOutbox: Record "Email Outbox";
+ ScheduleTasks: Record "Scheduled Task";
+ EmailMessage: Codeunit "Email Message";
+ ConnectorMock: Codeunit "Connector Mock";
+ AccountId: Guid;
+ DateTime: DateTime;
+ MaxDurationDifference: Duration;
+ begin
+ // [Scenario] When enqueuing an existing email, it appears in the outbox
+ PermissionsMock.Set('Email Edit');
+
+ // [Given] An email message and an email account
+ CreateEmail(EmailMessage);
+ Assert.IsTrue(EmailMessage.Get(EmailMessage.GetId()), 'The email should exist');
+ ConnectorMock.Initialize();
+ ConnectorMock.AddAccount(AccountId);
+
+ // [When] Enqueuing the email message with the email account
+ ScheduleTasks.DeleteAll();
+ ClearLastError();
+
+ DateTime := CreateDateTime(CalcDate('<+1D>', Today()), Time());
+ Email.Enqueue(EmailMessage, AccountId, Enum::"Email Connector"::"Test Email Connector", DateTime);
+
+ // [Then] No error occurs
+ Assert.AreEqual('', GetLastErrorText(), 'There should be no errors when enqueuing an email.');
+
+ // [Then] Job is enqueued
+ Assert.AreEqual(ScheduleTasks.Count, 1, 'Enqueue should only add one entry to scheduled tasks');
+ Assert.IsTrue(ScheduleTasks.FindFirst(), 'The job should be in scheduled tasks');
+ MaxDurationDifference := 100; // 100 ms
+ Assert.AreEqualDateTime(ScheduleTasks."Not Before", DateTime, MaxDurationDifference, 'The jobs not before date should be equal to the datetime provided when enqueueing');
+
+ // [Then] The enqueued email should be the correct one
+ EmailOutbox.SetRange("Message Id", EmailMessage.GetId());
+ Assert.AreEqual(1, EmailOutbox.Count(), 'There should be only one enqueued message');
+ Assert.IsTrue(EmailOutbox.FindFirst(), 'The message should be queued');
+
+ Assert.AreEqual(AccountId, EmailOutbox."Account Id", 'The account should be set');
+ Assert.AreEqual(Enum::"Email Connector"::"Test Email Connector", EmailOutbox.Connector, 'The connector should be set');
+ Assert.AreEqual(EmailOutbox.Status::Queued, EmailOutbox.Status, 'The status should be ''Queued''');
+ Assert.AreEqual(UserSecurityId(), EmailOutbox."User Security Id", 'The user security ID should be the current user');
+ Assert.AreEqual(EmailMessage.GetSubject(), EmailOutbox.Description, 'The description does not match the email title');
+ Assert.AreEqual('', EmailOutbox."Error Message", 'The error message should be blank');
+ Assert.AreEqual(DateTime, EmailOutbox."Date Sending", 'The date sending does not match the datetime provided when enqueueing');
+ end;
+
+ [Test]
+ [Scope('OnPrem')]
+ procedure SendEmailMessageFailTest()
+ var
+ EmailOutbox: Record "Email Outbox";
+ EmailMessage: Codeunit "Email Message";
+ ConnectorMock: Codeunit "Connector Mock";
+ Connector: Enum "Email Connector";
+ EmailStatus: Enum "Email Status";
+ AccountId: Guid;
+ begin
+ // [Scenario] When sending an email on the foreground and the process fails, an error is shown
+ PermissionsMock.Set('Email Edit');
+
+ // [Given] An email message and an email account
+ CreateEmail(EmailMessage);
+ Assert.IsTrue(EmailMessage.Get(EmailMessage.GetId()), 'The email should exist');
+ ConnectorMock.Initialize();
+ ConnectorMock.AddAccount(AccountId);
+
+ // [When] Sending the email fails
+ ConnectorMock.FailOnSend(true);
+ Assert.IsFalse(Email.Send(EmailMessage, AccountId, Connector::"Test Email Connector"), 'Sending an email should have failed');
+
+ // [Then] The error is as expected
+ EmailOutbox.SetRange("Account Id", AccountId);
+ EmailOutbox.SetRange("Message Id", EmailMessage.GetId());
+
+ Assert.IsTrue(EmailOutbox.FindFirst(), 'The email outbox entry should exist');
+ Assert.AreEqual(Connector::"Test Email Connector".AsInteger(), EmailOutbox.Connector.AsInteger(), 'Wrong connector');
+ Assert.AreEqual(EmailStatus::Failed.AsInteger(), EmailOutbox.Status.AsInteger(), 'Wrong status');
+ Assert.AreEqual('Failed to send email', EmailOutbox."Error Message", 'Wrong error message');
+ end;
+
+ [Test]
+ [Scope('OnPrem')]
+ procedure SendEmailMessageSuccessTest()
+ var
+ EmailOutbox: Record "Email Outbox";
+ EmailMessageAttachment: Record "Email Message Attachment";
+ SentEmail: Record "Sent Email";
+ EmailAccount: Record "Email Account";
+ EmailMessage: Codeunit "Email Message";
+ ConnectorMock: Codeunit "Connector Mock";
+ Connector: Enum "Email Connector";
+ begin
+ // [Scenario] When successfuly sending an email, a recond is added on the Sent Emails table
+ PermissionsMock.Set('Email Edit');
+
+ // [Given] An email message and an email account
+ CreateEmail(EmailMessage);
+ EmailMessage.AddAttachment('Attachment1', 'text/plain', Base64Convert.ToBase64('Content'));
+
+ Assert.IsTrue(EmailMessage.Get(EmailMessage.GetId()), 'The email should exist');
+
+ ConnectorMock.Initialize();
+ ConnectorMock.AddAccount(EmailAccount);
+
+ // [When] The email is Sent
+ Assert.IsTrue(Email.Send(EmailMessage, EmailAccount), 'Sending an email should have succeeded');
+
+ // [Then] There is a Sent Mail recond and no Outbox record
+ SentEmail.SetRange("Account Id", EmailAccount."Account Id");
+ SentEmail.SetRange("Message Id", EmailMessage.GetId());
+
+ Assert.IsTrue(SentEmail.FindFirst(), 'The email sent record should exist');
+ Assert.AreEqual(EmailMessage.GetId(), SentEmail."Message Id", 'Wrong email message');
+ Assert.AreEqual(EmailAccount."Email Address", SentEmail."Sent From", 'Wrong email address (sent from)');
+ Assert.AreNotEqual(0DT, SentEmail."Date Time Sent", 'The Date Time Sent should be filled');
+ Assert.AreEqual(EmailAccount."Account Id", SentEmail."Account Id", 'Wrong account');
+ Assert.AreEqual(Connector::"Test Email Connector".AsInteger(), SentEmail.Connector.AsInteger(), 'Wrong connector');
+ Assert.AreEqual(EmailMessage.GetSubject(), SentEmail.Description, 'Wrong description');
+
+ // There is no related outbox
+ EmailOutbox.SetRange("Account Id", EmailAccount."Account Id");
+ EmailOutbox.SetRange("Message Id", EmailMessage.GetId());
+
+ Assert.AreEqual(0, EmailOutbox.Count(), 'Email Outbox was not empty.');
+
+ //[Then] The attachments cannot be deleted
+ EmailMessageAttachment.SetRange("Email Message Id", EmailMessage.GetId());
+ EmailMessageAttachment.FindFirst();
+
+ asserterror EmailMessageAttachment.Delete();
+ Assert.ExpectedError(EmailMessageSentCannotDeleteAttachmentErr);
+ end;
+
+ [Test]
+ [Scope('OnPrem')]
+ procedure ShowSourceRecordInOutbox()
+ var
+ EmailOutbox: Record "Email Outbox";
+ EmailMessage: Codeunit "Email Message";
+ Any: Codeunit Any;
+ EmailTest: Codeunit "Email Test";
+ EmailOutboxPage: Page "Email Outbox";
+ EmailOutboxTestPage: TestPage "Email Outbox";
+ TableId: Integer;
+ SystemId: Guid;
+ begin
+ BindSubscription(EmailTest);
+
+ PermissionsMock.Set('Email Edit');
+
+ // [Scenario] Emails with source document, will see the Source Document button
+ // [Given] An Email with table id and source system id
+ TableId := Any.IntegerInRange(1, 10000);
+ SystemId := Any.GuidValue();
+
+ // [When] The email is created and saved as draft
+ CreateEmailWithSource(EmailMessage, TableId, SystemId);
+
+ // [When] The email is created and saved as draft
+ Email.SaveAsDraft(EmailMessage, EmailOutbox);
+
+ // [And] The Show Source Document button is visible
+ EmailOutboxTestPage.Trap();
+ EmailOutboxPage.SetRecord(EmailOutbox);
+ EmailOutboxPage.Run();
+
+ Assert.IsTrue(EmailOutboxTestPage.ShowSourceRecord.Visible(), 'Show Source Record action should be visible');
+
+ // [When] Show Source Document button is clicked
+ ClearLastError();
+ EmailOutboxTestPage.ShowSourceRecord.Invoke();
+
+ // [Then] No error appears
+ Assert.AreEqual('', GetLastErrorText, 'An error occured');
+ end;
+
+ [Test]
+ [Scope('OnPrem')]
+ [HandlerFunctions('RelationPickerHandler')]
+ procedure ShowMultipleSourceRecords()
+ var
+ EmailOutbox: Record "Email Outbox";
+ EmailMessageRecord: Record "Email Message";
+ EmailMessage: Codeunit "Email Message";
+ EmailTest: Codeunit "Email Test";
+ EmailOutboxPage: Page "Email Outbox";
+ EmailOutboxTestPage: TestPage "Email Outbox";
+ TableId: Integer;
+ SystemId: Guid;
+ begin
+ BindSubscription(EmailTest);
+ EmailOutbox.DeleteAll();
+
+ // [Scenario] Emails with multiple source documents, will see the email relation picker
+ // [Given] An Email with table id and source system id
+
+ // [And] The email is with a source and saved as draft
+ CreateEmail(EmailMessage);
+ Email.SaveAsDraft(EmailMessage, EmailOutbox);
+
+ // [When] An extra relation is added - We use email outbox to have a record that actually exists
+ EmailMessageRecord.Get(EmailMessage.GetId());
+ TableId := Database::"Email Outbox";
+ SystemId := EmailOutbox.SystemId;
+ Email.AddRelation(EmailMessage, TableId, SystemId, Enum::"Email Relation Type"::"Primary Source", Enum::"Email Relation Origin"::"Compose Context");
+ Email.AddRelation(EmailMessage, Database::"Email Message", EmailMessageRecord.SystemId, Enum::"Email Relation Type"::"Related Entity", Enum::"Email Relation Origin"::"Compose Context");
+
+ // [And] The Show Source Document button is clicked
+ EmailOutboxTestPage.Trap();
+ EmailOutboxPage.SetRecord(EmailOutbox);
+ EmailOutboxPage.Run();
+
+ Assert.IsTrue(EmailOutboxTestPage.ShowSourceRecord.Visible(), 'Show Source Record action should be visible');
+ Assert.IsTrue(EmailOutboxTestPage.ShowSourceRecord.Enabled(), 'Show Source Record action should be enabled');
+ EmailOutboxTestPage.ShowSourceRecord.Invoke();
+
+ // [Then] Email picker modal appears
+ end;
+
+ [Test]
+ [Scope('OnPrem')]
+ procedure EmailWithoutSourceInOutbox()
+ var
+ EmailOutbox: Record "Email Outbox";
+ EmailMessage: Codeunit "Email Message";
+ EmailTest: Codeunit "Email Test";
+ EmailOutboxPage: Page "Email Outbox";
+ EmailOutboxTestPage: TestPage "Email Outbox";
+ begin
+ BindSubscription(EmailTest);
+
+ PermissionsMock.Set('Email Edit');
+ EmailOutbox.DeleteAll();
+
+ // [Scenario] Emails with source document, will see the Source Document button
+ // [Given] An Email with table id and source system id
+
+ // [When] The email is created and saved as draft
+ CreateEmail(EmailMessage);
+ Email.SaveAsDraft(EmailMessage, EmailOutbox);
+
+ // [When] The Email Outbox page is opened.
+ EmailOutboxTestPage.Trap();
+ EmailOutboxPage.SetRecord(EmailOutbox);
+ EmailOutboxPage.Run();
+
+ // [Then] The Show Source action is visible and disabled.
+ Assert.IsTrue(EmailOutboxTestPage.ShowSourceRecord.Visible(), 'Show Source Record action should be visible');
+ Assert.IsFalse(EmailOutboxTestPage.ShowSourceRecord.Enabled(), 'Show Source Record action should be disabled');
+ end;
+
+
+ [Test]
+ [Scope('OnPrem')]
+ procedure EmailWithSourceNoSubscriber()
+ var
+ EmailOutbox: Record "Email Outbox";
+ EmailMessage: Codeunit "Email Message";
+ Any: Codeunit Any;
+ EmailOutboxPage: Page "Email Outbox";
+ EmailOutboxTestPage: TestPage "Email Outbox";
+ TableId: Integer;
+ SystemId: Guid;
+ begin
+ // [Scenario] Emails with source document, will see the Source Document button
+ PermissionsMock.Set('Email Edit');
+
+ // [Given] An Email with table id and source system id
+ TableId := Any.IntegerInRange(1, 10000);
+ SystemId := Any.GuidValue();
+
+ // [When] The email is created and saved as draft
+ CreateEmailWithSource(EmailMessage, TableId, SystemId);
+
+ // [When] The email is created and saved as draft
+ CreateEmail(EmailMessage);
+ Email.SaveAsDraft(EmailMessage, EmailOutbox);
+
+ // [When] The Email Outbox page is opened.
+ EmailOutboxTestPage.Trap();
+ EmailOutboxPage.SetRecord(EmailOutbox);
+ EmailOutboxPage.Run();
+
+ // [Then] The Show Source action is visible and disabled.
+ Assert.IsTrue(EmailOutboxTestPage.ShowSourceRecord.Visible(), 'Show Source Record action should be visible');
+ Assert.IsFalse(EmailOutboxTestPage.ShowSourceRecord.Enabled(), 'Show Source Record action should be disabled');
+ end;
+
+ [Test]
+ [Scope('OnPrem')]
+ procedure SendEmailMessageWithSourceTest()
+ var
+ TempSentEmail: Record "Sent Email" temporary;
+ EmailAccount: Record "Email Account";
+ EmailMessage: Codeunit "Email Message";
+ ConnectorMock: Codeunit "Connector Mock";
+ Any: Codeunit Any;
+ SystemId: Guid;
+ TableId, NumberOfEmails, i : Integer;
+ MessageIds: List of [Guid];
+ begin
+ // [Scenario] When successfuly sending an email with source, a record is added to the email source document table and sent emails table.
+ PermissionsMock.Set('Email Edit');
+
+ // [Given] An email with source and an email account
+ TableId := Any.IntegerInRange(1, 10000);
+ SystemId := Any.GuidValue();
+
+ ConnectorMock.Initialize();
+ ConnectorMock.AddAccount(EmailAccount);
+
+ NumberOfEmails := Any.IntegerInRange(2, 5);
+
+ for i := 1 to NumberOfEmails do begin
+ CreateEmailWithSource(EmailMessage, TableId, SystemId);
+ Assert.IsTrue(EmailMessage.Get(EmailMessage.GetId()), 'The email should exist');
+ MessageIds.Add(EmailMessage.GetId());
+
+ // [When] The email is Sent
+ Assert.IsTrue(Email.Send(EmailMessage, EmailAccount), 'Sending an email should have succeeded');
+ end;
+
+ Email.GetSentEmailsForRecord(TableId, SystemId, TempSentEmail);
+
+ for i := 1 to NumberOfEmails do begin
+ TempSentEmail.SetCurrentKey("Message Id");
+ TempSentEmail.SetRange("Message Id", MessageIds.Get(i));
+ Assert.AreEqual(1, TempSentEmail.Count(), 'Did not find the email in Sent Emails ');
+ end;
+ end;
+
+ [Test]
+ [Scope('OnPrem')]
+ [HandlerFunctions('RelatedAttachmentsHandler,CloseEmailEditorHandler')]
+ procedure AttachFromRelatedRecords()
+ var
+ EmailMessageAttachments: Record "Email Message Attachment";
+ EmailOutbox: Record "Email Outbox";
+ EmailMessage: Codeunit "Email Message";
+ EmailTest: Codeunit "Email Test";
+ EmailEditorPage: TestPage "Email Editor";
+ TableId: Integer;
+ SystemId: Guid;
+ SourceText: Text;
+ begin
+ BindSubscription(EmailTest);
+ VariableStorage.Clear();
+
+ // [Given] A created email
+ CreateEmail(EmailMessage);
+ Email.SaveAsDraft(EmailMessage, EmailOutbox);
+
+ // [And] A related record to the email (in this case, the email is related to an email in the outbox)
+ TableId := Database::"Email Outbox";
+ SystemId := EmailOutbox.SystemId;
+
+ Email.AddRelation(EmailMessage, TableId, SystemId, Enum::"Email Relation Type"::"Primary Source", Enum::"Email Relation Origin"::"Compose Context");
+
+ SourceText := StrSubstNo(OutboxSourceTextLbl, EmailOutbox.TableCaption(), Format(EmailOutbox.Id));
+ VariableStorage.Enqueue(SourceText);
+
+ // [When] Opening the Email Related Attachments page
+ EmailEditorPage.Trap();
+ Email.OpenInEditor(EmailMessage);
+ EmailEditorPage.Attachments.SourceAttachments.Invoke();
+
+ // [Then] Attachments added through the 'OnFindRelatedAttachments' event are displayed
+ // [And] A related attachment is added
+
+ // [Then] The related attachment is added as an attachment to the email
+ EmailMessageAttachments.SetRange("Email Message Id", EmailMessage.GetId());
+ EmailMessageAttachments.FindSet();
+ Assert.AreEqual(1, EmailMessageAttachments.Count(), 'Related attachment wasnt attached to the email.');
+ Assert.AreEqual('Attachment1', EmailMessageAttachments."Attachment Name", 'Wrong attachment was attached to email.');
+ AssertVariableStorageEmpty();
+ end;
+
+ [Test]
+ [Scope('OnPrem')]
+ procedure GetRelatedAttachmentsTest()
+ var
+ EmailRelatedAttachment: Record "Email Related Attachment";
+ EmailOutbox: Record "Email Outbox";
+ EmailMessage: Codeunit "Email Message";
+ EmailTest: Codeunit "Email Test";
+ EmailEditor: Codeunit "Email Editor";
+ TableId: Integer;
+ SystemId: Guid;
+ SourceText: Text;
+ begin
+ BindSubscription(EmailTest);
+ VariableStorage.Clear();
+
+ // [Given] A created email
+ CreateEmail(EmailMessage);
+ Email.SaveAsDraft(EmailMessage, EmailOutbox);
+
+ // [And] A related record to the email (in this case, the email is related to an email in the outbox)
+ TableId := Database::"Email Outbox";
+ SystemId := EmailOutbox.SystemId;
+
+ Email.AddRelation(EmailMessage, TableId, SystemId, Enum::"Email Relation Type"::"Primary Source", Enum::"Email Relation Origin"::"Compose Context");
+
+ SourceText := StrSubstNo(OutboxSourceTextLbl, EmailOutbox.TableCaption(), Format(EmailOutbox.Id));
+ VariableStorage.Enqueue(SourceText);
+
+ EmailEditor.GetRelatedAttachments(EmailMessage.GetId(), EmailRelatedAttachment);
+
+ Assert.AreEqual(1, EmailRelatedAttachment.Count(), 'Wrong number of attachments.');
+ Assert.AreEqual('Attachment1', EmailRelatedAttachment."Attachment Name", 'Wrong attachmentname');
+ end;
+
+ [Test]
+ [Scope('OnPrem')]
+ [HandlerFunctions('RelatedAttachmentsHandler,CloseEmailEditorHandler')]
+ procedure FailedAttachFromRelatedRecords()
+ var
+ EmailMessage: Codeunit "Email Message";
+ EmailTest: Codeunit "Email Test";
+ EmailEditorPage: TestPage "Email Editor";
+ begin
+ BindSubscription(EmailTest);
+
+ // [Given] A created email without source record
+ CreateEmail(EmailMessage);
+
+ // [When] Opening the Email Related Attachments page and getting related attachments
+ EmailEditorPage.Trap();
+ Email.OpenInEditor(EmailMessage);
+ asserterror EmailEditorPage.Attachments.SourceAttachments.Invoke();
+
+ // [Then] An error message is displayed
+ Assert.ExpectedError(NoRelatedAttachmentsErr);
+ end;
+
+ [Test]
+ [Scope('OnPrem')]
+ procedure SendEmailInBackgroundSuccessTest()
+ var
+ EmailAccount: Record "Email Account";
+ EmailMessage: Codeunit "Email Message";
+ ConnectorMock: Codeunit "Connector Mock";
+ TestClientType: Codeunit "Test Client Type Subscriber";
+ EmailTest: Codeunit "Email Test";
+ Variable: Variant;
+ Status: Boolean;
+ MessageID: Guid;
+ begin
+ // [Scenario] When Sending the email in the background an event is fired to nothify for the status of the email
+ PermissionsMock.Set('Email Edit');
+
+ TestClientType.SetClientType(ClientType::Background);
+ BindSubscription(TestClientType);
+ BindSubscription(EmailTest);
+
+ // [Given] An email message and an email account
+ CreateEmail(EmailMessage);
+ Assert.IsTrue(EmailMessage.Get(EmailMessage.GetId()), 'The email should exist');
+
+ ConnectorMock.Initialize();
+ ConnectorMock.AddAccount(EmailAccount);
+
+ // [When] The email is Sent
+ Email.Send(EmailMessage, EmailAccount);
+
+ // [Then] An event is fired to notify for the status of the email
+ EmailTest.DequeueVariable(Variable);
+ MessageID := Variable;
+ EmailTest.DequeueVariable(Variable);
+ Status := Variable;
+
+ // [Then] The event was fired once
+ EmailTest.AssertVariableStorageEmpty();
+ Assert.AreEqual(MessageID, EmailMessage.GetId(), 'A different Email was expected');
+ Assert.IsTrue(Status, 'The email should have been sent');
+
+ UnBindSubscription(EmailTest);
+ UnBindSubscription(TestClientType);
+ end;
+
+ [Test]
+ [Scope('OnPrem')]
+ procedure SendEmailInBackgroundFailTest()
+ var
+ EmailAccount: Record "Email Account";
+ EmailMessage: Codeunit "Email Message";
+ ConnectorMock: Codeunit "Connector Mock";
+ TestClientType: Codeunit "Test Client Type Subscriber";
+ EmailTest: Codeunit "Email Test";
+ Variable: Variant;
+ Status: Boolean;
+ MessageID: Guid;
+ begin
+ // [Scenario] When Sending the email in the background an event is fired to nothify for the status of the email
+ PermissionsMock.Set('Email Edit');
+
+ TestClientType.SetClientType(ClientType::Background);
+ BindSubscription(TestClientType);
+ BindSubscription(EmailTest);
+
+ // [Given] An email message and an email account
+ CreateEmail(EmailMessage);
+ Assert.IsTrue(EmailMessage.Get(EmailMessage.GetId()), 'The email should exist');
+
+ ConnectorMock.Initialize();
+ ConnectorMock.AddAccount(EmailAccount);
+ ConnectorMock.FailOnSend(true);
+
+ // [When] The email is Sent
+ Email.Send(EmailMessage, EmailAccount);
+
+ // [Then] An event is fired to notify for the status of the email
+ EmailTest.DequeueVariable(Variable);
+ MessageID := Variable;
+ EmailTest.DequeueVariable(Variable);
+ Status := Variable;
+
+ // [Then] The event was fired once
+ EmailTest.AssertVariableStorageEmpty();
+ Assert.AreEqual(MessageID, EmailMessage.GetId(), 'A different Email was expected');
+ Assert.IsFalse(Status, 'The email should not have been sent');
+
+ UnBindSubscription(EmailTest);
+ UnBindSubscription(TestClientType);
+ end;
+
+ [Test]
+ [Scope('OnPrem')]
+ procedure SendEmailInBackgroundFailSubscriberFailsTest()
+ var
+ EmailAccount: Record "Email Account";
+ EmailMessage: Codeunit "Email Message";
+ ConnectorMock: Codeunit "Connector Mock";
+ TestClientType: Codeunit "Test Client Type Subscriber";
+ EmailTest: Codeunit "Email Test";
+ Variable: Variant;
+ Status: Boolean;
+ MessageID: Guid;
+ begin
+ // [Scenario] When an error occurs on the subscriber it does not propagate up the stack and the notification is sent only once
+ PermissionsMock.Set('Email Edit');
+
+ TestClientType.SetClientType(ClientType::Background);
+ BindSubscription(TestClientType);
+ BindSubscription(EmailTest);
+ EmailTest.ThrowErrorOnAfterSendEmail();
+
+ // [Given] An email message and an email account
+ CreateEmail(EmailMessage);
+
+ Assert.IsTrue(EmailMessage.Get(EmailMessage.GetId()), 'The email should exist');
+
+ ConnectorMock.Initialize();
+ ConnectorMock.AddAccount(EmailAccount);
+ ConnectorMock.FailOnSend(true);
+
+ // [When] The email is Sent
+ Email.Send(EmailMessage, EmailAccount);
+
+ // [Then] An event is fired to notify for the status of the email
+ EmailTest.DequeueVariable(Variable);
+ MessageID := Variable;
+ EmailTest.DequeueVariable(Variable);
+ Status := Variable;
+
+ // [Then] The event was fired once
+ EmailTest.AssertVariableStorageEmpty();
+ Assert.AreEqual(MessageID, EmailMessage.GetId(), 'A different Email was expected');
+ Assert.IsFalse(Status, 'The email should not have been sent');
+
+ UnBindSubscription(EmailTest);
+ UnBindSubscription(TestClientType);
+ end;
+
+
+ [Test]
+ [Scope('OnPrem')]
+ procedure SendEmailInBackgroundSuccessSubscriberFailsTest()
+ var
+ EmailAccount: Record "Email Account";
+ EmailOutbox: Record "Email Outbox";
+ EmailMessage: Codeunit "Email Message";
+ ConnectorMock: Codeunit "Connector Mock";
+ TestClientType: Codeunit "Test Client Type Subscriber";
+ EmailTest: Codeunit "Email Test";
+ Variable: Variant;
+ Status: Boolean;
+ MessageID: Guid;
+ begin
+ // [Scenario] When an error occurs on the subscriber it does not propagate up the stack and the notification is sent only once
+ PermissionsMock.Set('Email Edit');
+
+ TestClientType.SetClientType(ClientType::Background);
+ BindSubscription(TestClientType);
+ BindSubscription(EmailTest);
+ EmailTest.ThrowErrorOnAfterSendEmail();
+
+ // [Given] An email message and an email account
+ CreateEmail(EmailMessage);
+
+ Assert.IsTrue(EmailMessage.Get(EmailMessage.GetId()), 'The email should exist');
+
+ ConnectorMock.Initialize();
+ ConnectorMock.AddAccount(EmailAccount);
+
+ // [When] The email is Sent
+ Email.Send(EmailMessage, EmailAccount);
+
+ // [Then] An event is fired to notify for the status of the email
+ EmailTest.DequeueVariable(Variable);
+ MessageID := Variable;
+ EmailTest.DequeueVariable(Variable);
+ Status := Variable;
+ // [Then] The event was fired once
+ EmailTest.AssertVariableStorageEmpty();
+ Assert.AreEqual(MessageID, EmailMessage.GetId(), 'A different Email was expected');
+ Assert.IsTrue(Status, 'The email should have been sent');
+
+ EmailOutbox.SetRange("Message Id", EmailMessage.GetId());
+ Assert.IsTrue(EmailOutbox.IsEmpty(), 'Email outbox should have been deleted.');
+
+ UnBindSubscription(EmailTest);
+ UnBindSubscription(TestClientType);
+ end;
+
+ [Test]
+ procedure ResendSentEmailFromAnotherUserTest()
+ var
+ SentEmail: Record "Sent Email";
+ Any: Codeunit Any;
+ EmailViewer: Codeunit "Email Viewer";
+ begin
+ // Create a sent email
+ PermissionsMock.Set('Email Edit');
+
+ SentEmail.Init();
+ SentEmail.Description := CopyStr(Any.UnicodeText(50), 1, MaxStrLen(SentEmail.Description));
+ SentEmail."Date Time Sent" := CurrentDateTime();
+ SentEmail."User Security Id" := CreateGuid(); // Created by another user
+ SentEmail.Insert();
+
+ asserterror EmailViewer.Resend(SentEmail);
+ Assert.ExpectedError(EmailMessageOpenPermissionErr);
+
+ asserterror EmailViewer.EditAndSend(SentEmail);
+ Assert.ExpectedError(EmailMessageOpenPermissionErr);
+ end;
+
+ [Test]
+ procedure GetSourceRecordInOutbox()
+ var
+ SourceEmailOutbox, EmailOutbox : Record "Email Outbox";
+ TempEmailOutbox: Record "Email Outbox" temporary;
+ EmailMessage: Codeunit "Email Message";
+ Any: Codeunit Any;
+ EmailTest: Codeunit "Email Test";
+ MessageIds: List of [Guid];
+ SystemId: Guid;
+ TableId: Integer;
+ NumberOfEmails, i : Integer;
+ begin
+ BindSubscription(EmailTest);
+
+ PermissionsMock.Set('Email Edit');
+ EmailOutbox.DeleteAll();
+
+ // [Scenario] Emails with source document, GetEmailOutboxForRecord procedure will return Outbox Emails
+ // [Given] Source Record - Email Outbox used as a source record for test email
+ CreateEmail(EmailMessage);
+ Email.SaveAsDraft(EmailMessage, SourceEmailOutbox);
+ TableId := Database::"Email Outbox";
+ SystemId := SourceEmailOutbox.SystemId;
+
+ // [When] Several emails are created and saved as draft
+ NumberOfEmails := Any.IntegerInRange(2, 5);
+
+ for i := 1 to NumberOfEmails do begin
+ Clear(EmailOutbox);
+ CreateEmailWithSource(EmailMessage, TableId, SystemId);
+ Email.SaveAsDraft(EmailMessage, EmailOutbox);
+ MessageIds.Add(EmailMessage.GetId());
+ end;
+
+ // [Then] GetEmailOutboxForRecord procedure return related Email Outbox
+ Email.GetEmailOutboxForRecord(SourceEmailOutbox, TempEmailOutbox);
+ Assert.AreEqual(NumberOfEmails, TempEmailOutbox.Count(), 'Email Outbox count is not equal to Number of Emails created.');
+
+ for i := 1 to NumberOfEmails do begin
+ TempEmailOutbox.SetCurrentKey("Message Id");
+ TempEmailOutbox.SetRange("Message Id", MessageIds.Get(i));
+ Assert.AreEqual(1, TempEmailOutbox.Count(), 'Did not find the email in Email Outbox');
+ end;
+ end;
+
+ [Test]
+ procedure GetEmailOutboxRecordStatus()
+ var
+ EmailOutbox: Record "Email Outbox";
+ EmailMessage: Codeunit "Email Message";
+ Any: Codeunit Any;
+ EmailTest: Codeunit "Email Test";
+ EmailStatus: Enum "Email Status";
+ TableId: Integer;
+ SystemId: Guid;
+ begin
+ BindSubscription(EmailTest);
+
+ PermissionsMock.Set('Email Edit');
+
+ // [Scenario] Emails with source document, GetOutboxEmailRecordStatus will return Outbox Email Status
+ // [Given] An Email with table id and source system id
+ TableId := Any.IntegerInRange(1, 10000);
+ SystemId := Any.GuidValue();
+
+ // [When] The email is created and saved as draft
+ CreateEmailWithSource(EmailMessage, TableId, SystemId);
+
+ // [When] The email is created and saved as draft
+ Email.SaveAsDraft(EmailMessage, EmailOutbox);
+
+ // [Then] Email Status of created Email Outbox record is equal to GetOutboxEmailRecordStatus result
+ EmailStatus := Email.GetOutboxEmailRecordStatus(EmailOutbox."Message Id");
+ Assert.AreEqual(EmailStatus, EmailOutbox.Status, 'Email Status should be the same as on Email Outbox record');
+ end;
+
+ [Test]
+ procedure GetSentEmailsForRecordByVariant()
+ var
+ SentEmail: Record "Sent Email";
+ TempSentEmail: Record "Sent Email" temporary;
+ EmailAccount: Record "Email Account";
+ EmailMessage: Codeunit "Email Message";
+ ConnectorMock: Codeunit "Connector Mock";
+ Any: Codeunit Any;
+ SystemId: Guid;
+ TableId, NumberOfEmails, i : Integer;
+ MessageIds: List of [Guid];
+ begin
+ // [Scenario] When successfuly sending an email with source, GetSentEmailsForRecord return related Sent Emails.
+ PermissionsMock.Set('Email Edit');
+ SentEmail.DeleteAll();
+
+ // [Given] An email with source and an email account
+ ConnectorMock.Initialize();
+ ConnectorMock.AddAccount(EmailAccount);
+ TableId := Database::"Email Account";
+ SystemId := EmailAccount.SystemId;
+ NumberOfEmails := Any.IntegerInRange(2, 5);
+
+ for i := 1 to NumberOfEmails do begin
+ CreateEmailWithSource(EmailMessage, TableId, SystemId);
+ Assert.IsTrue(EmailMessage.Get(EmailMessage.GetId()), 'The email should exist');
+ MessageIds.Add(EmailMessage.GetId());
+
+ // [When] The email is Sent
+ Assert.IsTrue(Email.Send(EmailMessage, EmailAccount), 'Sending an email should have succeeded');
+ end;
+
+ // [Then] GetSentEmailsForRecord procedure return related Sent Email records
+ Email.GetSentEmailsForRecord(EmailAccount, TempSentEmail);
+ Assert.AreEqual(NumberOfEmails, TempSentEmail.Count(), 'Sent Emails count is not equal to Number of Emails sent.');
+
+ for i := 1 to NumberOfEmails do begin
+ TempSentEmail.SetCurrentKey("Message Id");
+ TempSentEmail.SetRange("Message Id", MessageIds.Get(i));
+ Assert.AreEqual(1, TempSentEmail.Count(), 'Did not find the email in Sent Emails ');
+ end;
+ end;
+
+ local procedure CreateEmail(var EmailMessage: Codeunit "Email Message")
+ var
+ Any: Codeunit Any;
+ begin
+ EmailMessage.Create(Any.Email(), Any.UnicodeText(50), Any.UnicodeText(250), true);
+ end;
+
+ local procedure CreateEmailWithSource(var EmailMessage: Codeunit "Email Message"; TableId: Integer; SystemId: Guid)
+ var
+ Any: Codeunit Any;
+ begin
+ EmailMessage.Create(Any.Email(), Any.UnicodeText(50), Any.UnicodeText(250), true);
+ Email.AddRelation(EmailMessage, TableId, SystemId, Enum::"Email Relation Type"::"Primary Source", Enum::"Email Relation Origin"::"Compose Context");
+ end;
+
+ [StrMenuHandler]
+ [Scope('OnPrem')]
+ procedure CloseEmailEditorHandler(Options: Text[1024]; var Choice: Integer; Instruction: Text[1024])
+ begin
+ Choice := 1;
+ end;
+
+ [StrMenuHandler]
+ [Scope('OnPrem')]
+ procedure OnEmailEditorClose(Options: Text[1024]; var Choice: Integer; Instruction: Text[1024])
+ begin
+ Assert.AreEqual(InstructionTxt, Instruction, 'Wrong message when closing email editor');
+ Assert.AreEqual(OptionsOnClosePageTxt, Options, 'Wrong options when closing the email editor');
+
+ Choice := OptionChoice;
+ end;
+
+ [ModalPageHandler]
+ procedure RelationPickerHandler(var EmailRelationPickerTestPage: TestPage "Email Relation Picker")
+ begin
+ Assert.AreEqual(EmailRelationPickerTestPage."Relation Type".Value(), 'Primary Source', 'No source found on email relation picker page');
+
+ ClearLastError();
+ EmailRelationPickerTestPage."Source Name".Lookup();
+
+ Assert.AreEqual('', GetLastErrorText, 'An error occured - opening email relation from picker');
+ end;
+
+ [ModalPageHandler]
+ procedure RelatedAttachmentsHandler(var RelatedAttachmentsPage: TestPage "Email Related Attachments")
+ var
+ SourceLabel: Variant;
+ begin
+ RelatedAttachmentsPage.First();
+ DequeueVariable(SourceLabel);
+ Assert.AreEqual('Attachment1', RelatedAttachmentsPage.FileName.Value(), 'Wrong Attachment');
+ Assert.AreEqual(SourceLabel, RelatedAttachmentsPage.Source.Value(), 'Wrong Attachment');
+
+ RelatedAttachmentsPage.OK().Invoke();
+ end;
+
+ [ModalPageHandler]
+ procedure EmailEditorHandler(var EmailEditor: TestPage "Email Editor")
+ begin
+ Assert.IsTrue(EmailEditor.Account.Enabled(), 'Account field was not enabled');
+ Assert.IsTrue(EmailEditor.ToField.Editable(), 'To field was not editable');
+ Assert.IsTrue(EmailEditor.CcField.Editable(), 'Cc field was not editable');
+ Assert.IsTrue(EmailEditor.BccField.Editable(), 'Bcc field was not editable');
+ Assert.IsTrue(EmailEditor.SubjectField.Editable(), 'Subject field was not editable');
+ Assert.IsTrue(EmailEditor.BodyField.Editable(), 'Body field was not editable');
+ Assert.IsTrue(EmailEditor.Attachments.Upload.Visible(), 'Upload Action is not visible.');
+ Assert.IsTrue(EmailEditor.Send.Enabled(), 'Send Action was not enabled.');
+ end;
+
+ [ModalPageHandler]
+ procedure SendEmailEditorHandler(var EmailEditor: TestPage "Email Editor")
+ begin
+ EmailEditorHandler(EmailEditor);
+
+ EmailEditor.Send.Invoke();
+ end;
+
+ [ModalPageHandler]
+ procedure DiscardEmailEditorHandler(var EmailEditor: TestPage "Email Editor")
+ begin
+ EmailEditorHandler(EmailEditor);
+
+ EmailEditor.Discard.Invoke();
+ end;
+
+
+ [ConfirmHandler]
+ procedure ConfirmYes(Question: Text[1024]; var Reply: Boolean);
+ begin
+ Assert.AreEqual(DiscardEmailQst, Question, 'Wrong confirmation question');
+ Reply := true;
+ end;
+
+ [EventSubscriber(ObjectType::Codeunit, Codeunit::Email, 'OnAfterEmailSent', '', true, true)]
+ local procedure OnAfterEmailSentSubscriber(SentEmail: Record "Sent Email")
+ begin
+ VariableStorage.Enqueue(SentEmail."Message Id");
+ VariableStorage.Enqueue(true);
+ if ThrowError then
+ Error('');
+ end;
+
+ [EventSubscriber(ObjectType::Codeunit, Codeunit::Email, 'OnAfterEmailSendFailed', '', true, true)]
+ local procedure OnAfterEmailSendFailedSubscriber(EmailOutbox: Record "Email Outbox")
+ begin
+ VariableStorage.Enqueue(EmailOutbox."Message Id");
+ VariableStorage.Enqueue(false);
+ if ThrowError then
+ Error('');
+ end;
+
+ [EventSubscriber(ObjectType::Codeunit, Codeunit::Email, 'OnShowSource', '', true, true)]
+ local procedure OnShowSourceSubscriber(SourceTableId: Integer; SourceSystemId: Guid; var IsHandled: Boolean)
+ begin
+ IsHandled := true;
+ end;
+
+ [EventSubscriber(ObjectType::Codeunit, Codeunit::Email, 'OnFindRelatedAttachments', '', true, true)]
+ local procedure OnFindRelatedAttachments(SourceTableId: Integer; SourceSystemID: Guid; var EmailRelatedAttachments: Record "Email Related Attachment")
+ var
+ Any: Codeunit Any;
+ begin
+ EmailRelatedAttachments."Attachment Name" := 'Attachment1';
+ EmailRelatedAttachments."Attachment Table ID" := Any.IntegerInRange(1000);
+ EmailRelatedAttachments."Attachment System ID" := System.CreateGuid();
+ EmailRelatedAttachments.Insert();
+
+ end;
+
+ [EventSubscriber(ObjectType::Codeunit, Codeunit::Email, 'OnGetAttachment', '', true, true)]
+ local procedure OnGetAttachment(AttachmentTableID: Integer; AttachmentSystemID: Guid; MessageID: Guid)
+ var
+ EmailMessage: Codeunit "Email Message";
+ begin
+ EmailMessage.Get(MessageID);
+ EmailMessage.AddAttachment('Attachment1', 'text/plain', Base64Convert.ToBase64('Content'));
+ end;
+
+ procedure ThrowErrorOnAfterSendEmail()
+ begin
+ ThrowError := true;
+ end;
+
+ procedure DequeueVariable(var Variable: Variant)
+ begin
+ VariableStorage.Dequeue(Variable);
+ end;
+
+ procedure AssertVariableStorageEmpty()
+ begin
+ VariableStorage.AssertEmpty();
+ end;
+
+ var
+ VariableStorage: Codeunit "Library - Variable Storage";
+ InstructionTxt: Label 'The email has not been sent.';
+ OptionsOnClosePageTxt: Label 'Keep as draft in Email Outbox,Discard email';
+ DiscardEmailQst: Label 'Go ahead and discard?';
+ OptionChoice: Integer;
+ ThrowError: Boolean;
+}
\ No newline at end of file
diff --git a/src/System Application/Test/File System/src/Mocks/FileAccountsSelectionMock.Codeunit.al b/src/System Application/Test/File System/src/Mocks/FileAccountsSelectionMock.Codeunit.al
new file mode 100644
index 0000000000..d5f7400867
--- /dev/null
+++ b/src/System Application/Test/File System/src/Mocks/FileAccountsSelectionMock.Codeunit.al
@@ -0,0 +1,45 @@
+// ------------------------------------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License. See License.txt in the project root for license information.
+// ------------------------------------------------------------------------------------------------
+
+namespace System.Test.FileSystem;
+
+using System.FileSystem;
+
+///
+/// Used to mock selected email accounts on Email Accounts page.
+///
+codeunit 134697 "File System Acc Selection Mock"
+{
+ Access = Internal;
+ EventSubscriberInstance = Manual;
+
+ var
+ SelectionFilterLbl: Label '%1|%2', Locked = true;
+
+ internal procedure SelectAccount(AccountId: Guid)
+ begin
+ SelectedAccounts.Add(AccountId);
+ end;
+
+ [EventSubscriber(ObjectType::Codeunit, Codeunit::"File Account Impl.", 'OnAfterSetSelectionFilter', '', false, false)]
+ local procedure SelectAccounts(var FileAccount: Record "File Account")
+ var
+ SelectionFilter: Text;
+ AccountId: Guid;
+ begin
+ FileAccount.Reset();
+
+ foreach AccountId in SelectedAccounts do
+ SelectionFilter := StrSubstNo(SelectionFilterLbl, SelectionFilter, AccountId);
+
+ SelectionFilter := DelChr(SelectionFilter, '<>', '|'); // remove trailing and leading pipes
+
+ if SelectionFilter <> '' then
+ FileAccount.SetFilter("Account Id", SelectionFilter);
+ end;
+
+ var
+ SelectedAccounts: List of [Guid];
+}
\ No newline at end of file
From 62b73a70b599d5024ab383460a4ef132f9e981d1 Mon Sep 17 00:00:00 2001
From: Thomas Williamson
Date: Thu, 29 Feb 2024 17:58:18 +0100
Subject: [PATCH 02/43] Upgrade to BC24
---
.../App/File System/app.json | 49 +-
.../FileSystemAdmin.PermissionSet.al | 2 +-
.../FileSystemEdit.PermissionSet.al | 2 +-
.../FileSystemObjects.PermissionSetExt.al | 2 +-
.../FileSystemRead.PermissionSet.al | 2 +-
.../src/Account/FileAccount.Codeunit.al | 2 +-
.../src/Account/FileAccount.Table.al | 2 +-
.../src/Account/FileAccountImpl.Codeunit.al | 2 +-
.../src/Account/FileAccountWizard.Page.al | 2 +-
.../src/Account/FileAccounts.Page.al | 2 +-
.../src/Connector/FileSystemConnector.Enum.al | 2 +-
.../Connector/FileSystemConnector.Table.al | 2 +-
.../FileSystemConnectorLogo.Table.al | 2 +-
.../src/FileSystem/FileSystem.Codeunit.al | 2 +-
.../src/FileSystem/FileSystemImp.Codeunit.al | 2 +-
.../src/Lookup/FileAccountBrowser.Page.al | 2 +-
.../src/Lookup/FileAccountContent.Table.al | 2 +-
.../src/Lookup/FilePaginationData.Codeunit.al | 2 +-
.../File System/src/Lookup/FileType.Enum.al | 2 +-
.../src/Lookup/FolderNameInput.Page.al | 2 +-
.../src/Scenario/FileAccountScenario.Table.al | 2 +-
.../src/Scenario/FileScenario.Codeunit.al | 2 +-
.../src/Scenario/FileScenario.Enum.al | 2 +-
.../src/Scenario/FileScenario.Table.al | 2 +-
.../src/Scenario/FileScenarioImpl.Codeunit.al | 2 +-
.../src/Scenario/FileScenarioSetup.Page.al | 2 +-
.../src/Scenario/FileScenariosFactBox.Page.al | 2 +-
.../Scenario/FileScenariosForAccount.Page.al | 2 +-
.../Test Library/File System/app.json | 8 +-
.../File System/src/ConnectorMock.Codeunit.al | 17 -
.../src/TestFileConnectorSetup.Table.al | 4 -
.../src/TestFileSystemConnector.Codeunit.al | 10 -
.../Test/File System/app.json | 18 +-
.../src/FileAccountsTest.Codeunit.al | 372 ++--
.../src/FileScenarioPageTest.Codeunit.al | 144 +-
.../src/FileScenarioTest.Codeunit.al | 20 +-
.../src/FileSystemlTest.Codeunit.al | 1552 -----------------
.../FileAccountsSelectionMock.Codeunit.al | 2 +-
38 files changed, 281 insertions(+), 1969 deletions(-)
delete mode 100644 src/System Application/Test/File System/src/FileSystemlTest.Codeunit.al
diff --git a/src/System Application/App/File System/app.json b/src/System Application/App/File System/app.json
index e9b596cfbc..d88cfd431f 100644
--- a/src/System Application/App/File System/app.json
+++ b/src/System Application/App/File System/app.json
@@ -2,8 +2,8 @@
"id": "c9c54414-80c3-4cc9-98c6-589158882774",
"name": "File System",
"publisher": "Microsoft",
- "brief": "Enables user to send emails from Business Central.",
- "description": "Enables user to send emails from Business Central.",
+ "brief": "Enables access to external file systems from Business Central.",
+ "description": "Enables access to external file systems from Business Central.",
"version": "25.0.0.0",
"privacyStatement": "https://go.microsoft.com/fwlink/?linkid=724009",
"EULA": "https://go.microsoft.com/fwlink/?linkid=2009120",
@@ -11,7 +11,43 @@
"url": "https://go.microsoft.com/fwlink/?linkid=724011",
"logo": "",
"dependencies": [
- ],
+ {
+ "id": "7e3b999e-1182-45d2-8b82-d5127ddba9b2",
+ "name": "DotNet Aliases",
+ "publisher": "Microsoft",
+ "version": "25.0.0.0"
+ },
+ {
+ "id": "872fe7e8-9893-40ae-ab94-c123ed30fdbd",
+ "name": "Extension Management",
+ "publisher": "Microsoft",
+ "version": "25.0.0.0"
+ },
+ {
+ "id": "de35f591-7216-4e60-8be1-1911d71a7fc2",
+ "name": "Telemetry",
+ "publisher": "Microsoft",
+ "version": "25.0.0.0"
+ },
+ {
+ "id": "0846d207-5dec-4c1b-afd8-6a25e1e14b9d",
+ "name": "Base64 Convert",
+ "publisher": "Microsoft",
+ "version": "25.0.0.0"
+ },
+ {
+ "id": "a4584a53-9345-458a-af20-d1df2fab7bd8",
+ "name": "Confirm Management",
+ "publisher": "Microsoft",
+ "version": "25.0.0.0"
+ },
+ {
+ "id": "e31ad830-3d46-472e-afeb-1d3d35247943",
+ "name": "BLOB Storage",
+ "publisher": "Microsoft",
+ "version": "25.0.0.0"
+ }
+ ],
"internalsVisibleTo": [
{
"id": "fff6eee5-083f-4f07-9a49-e34f7e2aad77",
@@ -27,12 +63,11 @@
"screenshots": [
],
- "platform": "25.0.0.0",
- "application": "25.0.0.0",
+ "platform": "24.0.0.0",
"idRanges": [
{
- "from": 70000,
- "to": 70199
+ "from": 9450,
+ "to": 9459
}
],
"target": "OnPrem",
diff --git a/src/System Application/App/File System/permissions/FileSystemAdmin.PermissionSet.al b/src/System Application/App/File System/permissions/FileSystemAdmin.PermissionSet.al
index 45aaffabee..26d6e72537 100644
--- a/src/System Application/App/File System/permissions/FileSystemAdmin.PermissionSet.al
+++ b/src/System Application/App/File System/permissions/FileSystemAdmin.PermissionSet.al
@@ -5,7 +5,7 @@
namespace System.FileSystem;
-permissionset 70000 "File System - Admin"
+permissionset 9450 "File System - Admin"
{
Access = Public;
Assignable = true;
diff --git a/src/System Application/App/File System/permissions/FileSystemEdit.PermissionSet.al b/src/System Application/App/File System/permissions/FileSystemEdit.PermissionSet.al
index e4314d462b..8f27dfc1fb 100644
--- a/src/System Application/App/File System/permissions/FileSystemEdit.PermissionSet.al
+++ b/src/System Application/App/File System/permissions/FileSystemEdit.PermissionSet.al
@@ -7,7 +7,7 @@ namespace System.FileSystem;
using System.Environment;
-permissionset 70002 "File System - Read"
+permissionset 9451 "File System - Read"
{
Access = Internal;
Assignable = false;
diff --git a/src/System Application/App/File System/permissions/FileSystemObjects.PermissionSetExt.al b/src/System Application/App/File System/permissions/FileSystemObjects.PermissionSetExt.al
index de04bf3b01..43ad58750a 100644
--- a/src/System Application/App/File System/permissions/FileSystemObjects.PermissionSetExt.al
+++ b/src/System Application/App/File System/permissions/FileSystemObjects.PermissionSetExt.al
@@ -5,7 +5,7 @@
namespace System.FileSystem;
-permissionset 70001 "File System - Objects"
+permissionset 9452 "File System - Objects"
{
Access = Internal;
Assignable = false;
diff --git a/src/System Application/App/File System/permissions/FileSystemRead.PermissionSet.al b/src/System Application/App/File System/permissions/FileSystemRead.PermissionSet.al
index 43fb9e2e0d..5b9761bbb3 100644
--- a/src/System Application/App/File System/permissions/FileSystemRead.PermissionSet.al
+++ b/src/System Application/App/File System/permissions/FileSystemRead.PermissionSet.al
@@ -7,7 +7,7 @@ namespace System.FileSystem;
using System.Environment;
-permissionset 70003 "File System - Edit"
+permissionset 9453 "File System - Edit"
{
Access = Public;
Assignable = false;
diff --git a/src/System Application/App/File System/src/Account/FileAccount.Codeunit.al b/src/System Application/App/File System/src/Account/FileAccount.Codeunit.al
index d16f624814..1d97060fcf 100644
--- a/src/System Application/App/File System/src/Account/FileAccount.Codeunit.al
+++ b/src/System Application/App/File System/src/Account/FileAccount.Codeunit.al
@@ -9,7 +9,7 @@ namespace System.FileSystem;
/// Provides functionality to work with file accounts.
///
-codeunit 70000 "File Account"
+codeunit 9450 "File Account"
{
Access = Public;
diff --git a/src/System Application/App/File System/src/Account/FileAccount.Table.al b/src/System Application/App/File System/src/Account/FileAccount.Table.al
index e4317b2d2b..6c07eb775b 100644
--- a/src/System Application/App/File System/src/Account/FileAccount.Table.al
+++ b/src/System Application/App/File System/src/Account/FileAccount.Table.al
@@ -8,7 +8,7 @@ namespace System.FileSystem;
///
/// A common representation of an file account.
///
-table 70000 "File Account"
+table 9450 "File Account"
{
Extensible = false;
TableType = Temporary;
diff --git a/src/System Application/App/File System/src/Account/FileAccountImpl.Codeunit.al b/src/System Application/App/File System/src/Account/FileAccountImpl.Codeunit.al
index 2535a7b38a..f7dae371f0 100644
--- a/src/System Application/App/File System/src/Account/FileAccountImpl.Codeunit.al
+++ b/src/System Application/App/File System/src/Account/FileAccountImpl.Codeunit.al
@@ -8,7 +8,7 @@ namespace System.FileSystem;
using System.Utilities;
using System.Text;
-codeunit 70001 "File Account Impl."
+codeunit 9451 "File Account Impl."
{
Access = Internal;
InherentPermissions = X;
diff --git a/src/System Application/App/File System/src/Account/FileAccountWizard.Page.al b/src/System Application/App/File System/src/Account/FileAccountWizard.Page.al
index f18e1bad57..a1f57f8cc4 100644
--- a/src/System Application/App/File System/src/Account/FileAccountWizard.Page.al
+++ b/src/System Application/App/File System/src/Account/FileAccountWizard.Page.al
@@ -12,7 +12,7 @@ using System.Telemetry;
///
/// Step by step guide for adding a new file account in Business Central
///
-page 70001 "File Account Wizard"
+page 9451 "File Account Wizard"
{
PageType = NavigatePage;
ApplicationArea = All;
diff --git a/src/System Application/App/File System/src/Account/FileAccounts.Page.al b/src/System Application/App/File System/src/Account/FileAccounts.Page.al
index d069d9836c..9510fb0075 100644
--- a/src/System Application/App/File System/src/Account/FileAccounts.Page.al
+++ b/src/System Application/App/File System/src/Account/FileAccounts.Page.al
@@ -10,7 +10,7 @@ using System.Telemetry;
///
/// Lists all of the registered file accounts
///
-page 70000 "File Accounts"
+page 9450 "File Accounts"
{
PageType = List;
Caption = 'File Accounts';
diff --git a/src/System Application/App/File System/src/Connector/FileSystemConnector.Enum.al b/src/System Application/App/File System/src/Connector/FileSystemConnector.Enum.al
index 7cd7562bf2..9052f72749 100644
--- a/src/System Application/App/File System/src/Connector/FileSystemConnector.Enum.al
+++ b/src/System Application/App/File System/src/Connector/FileSystemConnector.Enum.al
@@ -8,7 +8,7 @@ namespace System.FileSystem;
///
/// Enum that holds all of the available file connectors.
///
-enum 70000 "File System Connector" implements "File System Connector"
+enum 9450 "File System Connector" implements "File System Connector"
{
Extensible = true;
}
\ No newline at end of file
diff --git a/src/System Application/App/File System/src/Connector/FileSystemConnector.Table.al b/src/System Application/App/File System/src/Connector/FileSystemConnector.Table.al
index 6795e622f2..b92c87e5e9 100644
--- a/src/System Application/App/File System/src/Connector/FileSystemConnector.Table.al
+++ b/src/System Application/App/File System/src/Connector/FileSystemConnector.Table.al
@@ -5,7 +5,7 @@
namespace System.FileSystem;
-table 70001 "File System Connector"
+table 9451 "File System Connector"
{
TableType = Temporary;
Access = Internal;
diff --git a/src/System Application/App/File System/src/Connector/FileSystemConnectorLogo.Table.al b/src/System Application/App/File System/src/Connector/FileSystemConnectorLogo.Table.al
index 6d3459eea1..ae58ecf2d3 100644
--- a/src/System Application/App/File System/src/Connector/FileSystemConnectorLogo.Table.al
+++ b/src/System Application/App/File System/src/Connector/FileSystemConnectorLogo.Table.al
@@ -5,7 +5,7 @@
namespace System.FileSystem;
-table 70002 "File System Connector Logo"
+table 9452 "File System Connector Logo"
{
DataClassification = SystemMetadata;
Access = Internal;
diff --git a/src/System Application/App/File System/src/FileSystem/FileSystem.Codeunit.al b/src/System Application/App/File System/src/FileSystem/FileSystem.Codeunit.al
index 41a19f67d8..acd2b0eafb 100644
--- a/src/System Application/App/File System/src/FileSystem/FileSystem.Codeunit.al
+++ b/src/System Application/App/File System/src/FileSystem/FileSystem.Codeunit.al
@@ -5,7 +5,7 @@
namespace System.FileSystem;
-codeunit 70004 "File System"
+codeunit 9454 "File System"
{
var
FileSystemImpl: Codeunit "File System Impl.";
diff --git a/src/System Application/App/File System/src/FileSystem/FileSystemImp.Codeunit.al b/src/System Application/App/File System/src/FileSystem/FileSystemImp.Codeunit.al
index c569119e64..2286317aeb 100644
--- a/src/System Application/App/File System/src/FileSystem/FileSystemImp.Codeunit.al
+++ b/src/System Application/App/File System/src/FileSystem/FileSystemImp.Codeunit.al
@@ -5,7 +5,7 @@
namespace System.FileSystem;
-codeunit 70005 "File System Impl."
+codeunit 9455 "File System Impl."
{
var
IFileConnector: Interface "File System Connector";
diff --git a/src/System Application/App/File System/src/Lookup/FileAccountBrowser.Page.al b/src/System Application/App/File System/src/Lookup/FileAccountBrowser.Page.al
index fec745954b..dcec939279 100644
--- a/src/System Application/App/File System/src/Lookup/FileAccountBrowser.Page.al
+++ b/src/System Application/App/File System/src/Lookup/FileAccountBrowser.Page.al
@@ -5,7 +5,7 @@
namespace System.FileSystem;
-page 70005 "File Account Browser"
+page 9455 "File Account Browser"
{
Caption = 'File Account Browser';
PageType = List;
diff --git a/src/System Application/App/File System/src/Lookup/FileAccountContent.Table.al b/src/System Application/App/File System/src/Lookup/FileAccountContent.Table.al
index f4ca1d3ead..3dab1f86c2 100644
--- a/src/System Application/App/File System/src/Lookup/FileAccountContent.Table.al
+++ b/src/System Application/App/File System/src/Lookup/FileAccountContent.Table.al
@@ -5,7 +5,7 @@
namespace System.FileSystem;
-table 70005 "File Account Content"
+table 9455 "File Account Content"
{
Caption = 'File Account Content';
DataClassification = SystemMetadata;
diff --git a/src/System Application/App/File System/src/Lookup/FilePaginationData.Codeunit.al b/src/System Application/App/File System/src/Lookup/FilePaginationData.Codeunit.al
index 6a5dc90cfc..3ebdd89743 100644
--- a/src/System Application/App/File System/src/Lookup/FilePaginationData.Codeunit.al
+++ b/src/System Application/App/File System/src/Lookup/FilePaginationData.Codeunit.al
@@ -5,7 +5,7 @@
namespace System.FileSystem;
-codeunit 70006 "File Pagination Data"
+codeunit 9456 "File Pagination Data"
{
var
Marker: Text;
diff --git a/src/System Application/App/File System/src/Lookup/FileType.Enum.al b/src/System Application/App/File System/src/Lookup/FileType.Enum.al
index 54f6ea811f..4f707a962a 100644
--- a/src/System Application/App/File System/src/Lookup/FileType.Enum.al
+++ b/src/System Application/App/File System/src/Lookup/FileType.Enum.al
@@ -8,7 +8,7 @@ namespace System.FileSystem;
///
/// Indicator of what type the resource is.
///
-enum 70002 "File Type"
+enum 9452 "File Type"
{
Access = Public;
Extensible = false;
diff --git a/src/System Application/App/File System/src/Lookup/FolderNameInput.Page.al b/src/System Application/App/File System/src/Lookup/FolderNameInput.Page.al
index 23239dcce3..04db3b7904 100644
--- a/src/System Application/App/File System/src/Lookup/FolderNameInput.Page.al
+++ b/src/System Application/App/File System/src/Lookup/FolderNameInput.Page.al
@@ -5,7 +5,7 @@
namespace System.FileSystem;
-page 70006 "Folder Name Input"
+page 9456 "Folder Name Input"
{
ApplicationArea = All;
Caption = 'Create Folder...';
diff --git a/src/System Application/App/File System/src/Scenario/FileAccountScenario.Table.al b/src/System Application/App/File System/src/Scenario/FileAccountScenario.Table.al
index 649a7b951e..df144f2e69 100644
--- a/src/System Application/App/File System/src/Scenario/FileAccountScenario.Table.al
+++ b/src/System Application/App/File System/src/Scenario/FileAccountScenario.Table.al
@@ -8,7 +8,7 @@ namespace System.FileSystem;
///
/// Temporary table used to display the tree sctructure in "File Scenario Setup".
///
-table 70003 "File Account Scenario"
+table 9453 "File Account Scenario"
{
Access = Internal;
InherentPermissions = X;
diff --git a/src/System Application/App/File System/src/Scenario/FileScenario.Codeunit.al b/src/System Application/App/File System/src/Scenario/FileScenario.Codeunit.al
index 46a191fb45..417e3fb945 100644
--- a/src/System Application/App/File System/src/Scenario/FileScenario.Codeunit.al
+++ b/src/System Application/App/File System/src/Scenario/FileScenario.Codeunit.al
@@ -8,7 +8,7 @@ namespace System.FileSystem;
///
/// Provides functionality to work with file scenarios.
///
-codeunit 70002 "File Scenario"
+codeunit 9452 "File Scenario"
{
///
/// Gets the default file account.
diff --git a/src/System Application/App/File System/src/Scenario/FileScenario.Enum.al b/src/System Application/App/File System/src/Scenario/FileScenario.Enum.al
index 7a31b1238c..7a98b32770 100644
--- a/src/System Application/App/File System/src/Scenario/FileScenario.Enum.al
+++ b/src/System Application/App/File System/src/Scenario/FileScenario.Enum.al
@@ -9,7 +9,7 @@ namespace System.FileSystem;
/// File scenarios.
/// Used to decouple file accounts from sending files.
///
-enum 70001 "File Scenario"
+enum 9451 "File Scenario"
{
Extensible = true;
diff --git a/src/System Application/App/File System/src/Scenario/FileScenario.Table.al b/src/System Application/App/File System/src/Scenario/FileScenario.Table.al
index 2258a9c28f..390a295715 100644
--- a/src/System Application/App/File System/src/Scenario/FileScenario.Table.al
+++ b/src/System Application/App/File System/src/Scenario/FileScenario.Table.al
@@ -10,7 +10,7 @@ namespace System.FileSystem;
/// One scenarios is mapped to one file account.
/// One file account can be used for multiple scenarios.
///
-table 70004 "File Scenario"
+table 9454 "File Scenario"
{
Access = Internal;
diff --git a/src/System Application/App/File System/src/Scenario/FileScenarioImpl.Codeunit.al b/src/System Application/App/File System/src/Scenario/FileScenarioImpl.Codeunit.al
index 6c0922fdfc..bf6932665b 100644
--- a/src/System Application/App/File System/src/Scenario/FileScenarioImpl.Codeunit.al
+++ b/src/System Application/App/File System/src/Scenario/FileScenarioImpl.Codeunit.al
@@ -7,7 +7,7 @@ namespace System.FileSystem;
using System;
-codeunit 70003 "File Scenario Impl."
+codeunit 9453 "File Scenario Impl."
{
Access = Internal;
InherentPermissions = X;
diff --git a/src/System Application/App/File System/src/Scenario/FileScenarioSetup.Page.al b/src/System Application/App/File System/src/Scenario/FileScenarioSetup.Page.al
index 2d6c1c1396..29a64a1b3f 100644
--- a/src/System Application/App/File System/src/Scenario/FileScenarioSetup.Page.al
+++ b/src/System Application/App/File System/src/Scenario/FileScenarioSetup.Page.al
@@ -10,7 +10,7 @@ using System.Telemetry;
///
/// Page is used to display file scenarios usage by file accounts.
///
-page 70002 "File Scenario Setup"
+page 9452 "File Scenario Setup"
{
Caption = 'File Scenario Assignment';
PageType = List;
diff --git a/src/System Application/App/File System/src/Scenario/FileScenariosFactBox.Page.al b/src/System Application/App/File System/src/Scenario/FileScenariosFactBox.Page.al
index df5bd47cc4..871119cebd 100644
--- a/src/System Application/App/File System/src/Scenario/FileScenariosFactBox.Page.al
+++ b/src/System Application/App/File System/src/Scenario/FileScenariosFactBox.Page.al
@@ -8,7 +8,7 @@ namespace System.FileSystem;
///
/// Lists of all scenarios assigned to an account.
///
-page 70003 "File Scenarios FactBox"
+page 9453 "File Scenarios FactBox"
{
PageType = ListPart;
Extensible = false;
diff --git a/src/System Application/App/File System/src/Scenario/FileScenariosForAccount.Page.al b/src/System Application/App/File System/src/Scenario/FileScenariosForAccount.Page.al
index ee44822462..d8691c5e8a 100644
--- a/src/System Application/App/File System/src/Scenario/FileScenariosForAccount.Page.al
+++ b/src/System Application/App/File System/src/Scenario/FileScenariosForAccount.Page.al
@@ -8,7 +8,7 @@ namespace System.FileSystem;
///
/// Displays the scenarios that could be linked to a provided file account.
///
-page 70004 "File Scenarios for Account"
+page 9454 "File Scenarios for Account"
{
PageType = List;
Extensible = false;
diff --git a/src/System Application/Test Library/File System/app.json b/src/System Application/Test Library/File System/app.json
index 0c98188146..f2611db303 100644
--- a/src/System Application/Test Library/File System/app.json
+++ b/src/System Application/Test Library/File System/app.json
@@ -2,8 +2,8 @@
"id": "f188754b-3ffb-443a-9507-f5fbdae3af2c",
"name": "File System Test Library",
"publisher": "Microsoft",
- "brief": "Test library for the Email module",
- "description": "Test library for the Email module",
+ "brief": "Test library for the File System module",
+ "description": "Test library for the File System module",
"version": "25.0.0.0",
"privacyStatement": "https://go.microsoft.com/fwlink/?linkid=724009",
"EULA": "https://go.microsoft.com/fwlink/?linkid=2009120",
@@ -21,13 +21,13 @@
"id": "e7320ebb-08b3-4406-b1ec-b4927d3e280b",
"name": "Any",
"publisher": "Microsoft",
- "version": "25.0.0.0"
+ "version": "24.0.0.0"
}
],
"screenshots": [
],
- "platform": "25.0.0.0",
+ "platform": "24.0.0.0",
"idRanges": [
{
"from": 80200,
diff --git a/src/System Application/Test Library/File System/src/ConnectorMock.Codeunit.al b/src/System Application/Test Library/File System/src/ConnectorMock.Codeunit.al
index e7f175e5da..79885c532c 100644
--- a/src/System Application/Test Library/File System/src/ConnectorMock.Codeunit.al
+++ b/src/System Application/Test Library/File System/src/ConnectorMock.Codeunit.al
@@ -116,21 +116,4 @@ codeunit 80200 "Connector Mock"
TestFileConnectorSetup."Unsuccessful Register" := Fail;
TestFileConnectorSetup.Modify();
end;
-
- procedure SetEmailMessageID(EmailMessageID: Guid)
- var
- TestFileConnectorSetup: Record "Test File Connector Setup";
- begin
- TestFileConnectorSetup.FindFirst();
- TestFileConnectorSetup."Email Message ID" := EmailMessageID;
- TestFileConnectorSetup.Modify();
- end;
-
- procedure GetEmailMessageID(): Guid
- var
- TestFileConnectorSetup: Record "Test File Connector Setup";
- begin
- TestFileConnectorSetup.FindFirst();
- exit(TestFileConnectorSetup."Email Message ID");
- end;
}
\ No newline at end of file
diff --git a/src/System Application/Test Library/File System/src/TestFileConnectorSetup.Table.al b/src/System Application/Test Library/File System/src/TestFileConnectorSetup.Table.al
index 6e23878497..f5791e5917 100644
--- a/src/System Application/Test Library/File System/src/TestFileConnectorSetup.Table.al
+++ b/src/System Application/Test Library/File System/src/TestFileConnectorSetup.Table.al
@@ -28,10 +28,6 @@ table 80201 "Test File Connector Setup"
{
Caption = 'Unsuccessful Register';
}
- field(5; "Email Message ID"; Guid)
- {
- Caption = 'Email Message ID';
- }
}
keys
diff --git a/src/System Application/Test Library/File System/src/TestFileSystemConnector.Codeunit.al b/src/System Application/Test Library/File System/src/TestFileSystemConnector.Codeunit.al
index 4d1dca2512..75d8e17e58 100644
--- a/src/System Application/Test Library/File System/src/TestFileSystemConnector.Codeunit.al
+++ b/src/System Application/Test Library/File System/src/TestFileSystemConnector.Codeunit.al
@@ -9,16 +9,6 @@ using System.FileSystem;
codeunit 80202 "Test File System Connector" implements "File System Connector"
{
- /*
- procedure Send(EmailMessage: Codeunit "Email Message"; AccountId: Guid)
- begin
- ConnectorMock.SetEmailMessageID(EmailMessage.GetId());
- Commit();
- if ConnectorMock.FailOnSend() then
- Error('Failed to send email');
- end;
-*/
-
procedure ListFiles(AccountId: Guid; Path: Text; FilePaginationData: Codeunit "File Pagination Data"; var FileAccountContent: Record "File Account Content" temporary);
begin
FileAccountContent.Init();
diff --git a/src/System Application/Test/File System/app.json b/src/System Application/Test/File System/app.json
index e6c9d1544d..25ca656ac3 100644
--- a/src/System Application/Test/File System/app.json
+++ b/src/System Application/Test/File System/app.json
@@ -21,19 +21,13 @@
"id": "f188754b-3ffb-443a-9507-f5fbdae3af2c",
"name": "File System Test Library",
"publisher": "Microsoft",
- "version": "25.0.0.0"
- },
- {
- "id": "47397d83-32ba-4ef0-8988-ef72539bfe36",
- "name": "Client Type Management Test Library",
- "publisher": "Microsoft",
- "version": "25.0.0.0"
+ "version": "24.0.0.0"
},
{
"id": "5095f467-0a01-4b99-99d1-9ff1237d286f",
"name": "Library Variable Storage",
"publisher": "Microsoft",
- "version": "25.0.0.0"
+ "version": "24.0.0.0"
},
{
"id": "e31ad830-3d46-472e-afeb-1d3d35247943",
@@ -51,25 +45,25 @@
"id": "dd0be2ea-f733-4d65-bb34-a28f4624fb14",
"name": "Library Assert",
"publisher": "Microsoft",
- "version": "25.0.0.0"
+ "version": "24.0.0.0"
},
{
"id": "e7320ebb-08b3-4406-b1ec-b4927d3e280b",
"name": "Any",
"publisher": "Microsoft",
- "version": "25.0.0.0"
+ "version": "24.0.0.0"
},
{
"id": "40860557-a18d-42ad-aecb-22b7dd80dc80",
"name": "Permissions Mock",
"publisher": "Microsoft",
- "version": "25.0.0.0"
+ "version": "24.0.0.0"
}
],
"screenshots": [
],
- "platform": "25.0.0.0",
+ "platform": "24.0.0.0",
"idRanges": [
{
"from": 134487,
diff --git a/src/System Application/Test/File System/src/FileAccountsTest.Codeunit.al b/src/System Application/Test/File System/src/FileAccountsTest.Codeunit.al
index b0d917430f..60cec7cc4e 100644
--- a/src/System Application/Test/File System/src/FileAccountsTest.Codeunit.al
+++ b/src/System Application/Test/File System/src/FileAccountsTest.Codeunit.al
@@ -36,12 +36,12 @@ codeunit 134686 "File Accounts Test"
ConnectorMock.Initialize();
ConnectorMock.AddAccount(FileAccount);
- PermissionsMock.Set('File Edit');
+ PermissionsMock.Set('File System Edit');
// [When] The accounts page is open
AccountsPage.OpenView();
- // [Then] The email entry is visible on the page
+ // [Then] The file entry is visible on the page
Assert.IsTrue(AccountsPage.GoToKey(FileAccount."Account Id", FileAccount.Connector), 'The File account should be on the page');
Assert.AreEqual(FileAccount.Name, Format(AccountsPage.NameField), 'The account name on the page is wrong');
@@ -52,7 +52,7 @@ codeunit 134686 "File Accounts Test"
[TransactionModel(TransactionModel::AutoRollback)]
procedure TwoAccountsAppearOnThePageTest()
var
- FirstEmailAccount, SecondEmailAccount : Record "File Account";
+ FirstFileAccount, SecondFileAccount : Record "File Account";
ConnectorMock: Codeunit "Connector Mock";
AccountsPage: TestPage "File Accounts";
begin
@@ -60,40 +60,20 @@ codeunit 134686 "File Accounts Test"
// [Given] Two File accounts
ConnectorMock.Initialize();
- ConnectorMock.AddAccount(FirstEmailAccount);
- ConnectorMock.AddAccount(SecondEmailAccount);
+ ConnectorMock.AddAccount(FirstFileAccount);
+ ConnectorMock.AddAccount(SecondFileAccount);
- PermissionsMock.Set('Email Edit');
+ PermissionsMock.Set('File System Edit');
// [When] The accounts page is open
AccountsPage.OpenView();
- // [Then] The email entries are visible on the page
- Assert.IsTrue(AccountsPage.GoToKey(FirstEmailAccount."Account Id", Enum::"File System Connector"::"Test File System Connector"), 'The first File account should be on the page');
- Assert.AreEqual(FirstEmailAccount.Name, Format(AccountsPage.NameField), 'The first account name on the page is wrong');
+ // [Then] The file entries are visible on the page
+ Assert.IsTrue(AccountsPage.GoToKey(FirstFileAccount."Account Id", Enum::"File System Connector"::"Test File System Connector"), 'The first File account should be on the page');
+ Assert.AreEqual(FirstFileAccount.Name, Format(AccountsPage.NameField), 'The first account name on the page is wrong');
- Assert.IsTrue(AccountsPage.GoToKey(SecondEmailAccount."Account Id", Enum::"File System Connector"::"Test File System Connector"), 'The second File account should be on the page');
- Assert.AreEqual(SecondEmailAccount.Name, Format(AccountsPage.NameField), 'The second account name on the page is wrong');
- end;
-
- [Test]
- [TransactionModel(TransactionModel::AutoRollback)]
- procedure IsAccountRegisteredTest()
- var
- EmailAccountRecord: Record "File Account";
- ConnectorMock: Codeunit "Connector Mock";
- EmailAccount: Codeunit "File Account";
- begin
- // [Scenario] When there's a File account for a connector, it should return true for IsAccountRegistered
-
- // [Given] An File account
- ConnectorMock.Initialize();
- ConnectorMock.AddAccount(EmailAccountRecord);
-
- PermissionsMock.Set('Email Edit');
-
- // [Then] The File account is registered
- Assert.IsTrue(EmailAccount.IsAccountRegistered(EmailAccountRecord."Account Id", EmailAccountRecord.Connector), 'The File account should be registered');
+ Assert.IsTrue(AccountsPage.GoToKey(SecondFileAccount."Account Id", Enum::"File System Connector"::"Test File System Connector"), 'The second File account should be on the page');
+ Assert.AreEqual(SecondFileAccount.Name, Format(AccountsPage.NameField), 'The second account name on the page is wrong');
end;
[Test]
@@ -105,7 +85,7 @@ codeunit 134686 "File Accounts Test"
AccountWizardPage: TestPage "File Account Wizard";
begin
// [SCENARIO] A new Account can be added through the Account Wizard
- PermissionsMock.Set('Email Admin');
+ PermissionsMock.Set('File System Admin');
ConnectorMock.Initialize();
@@ -121,13 +101,12 @@ codeunit 134686 "File Accounts Test"
Assert.IsTrue(AccountWizardPage.Name.Visible(), 'Connector Name should be visible');
Assert.IsTrue(AccountWizardPage.Details.Visible(), 'Connector Details should be visible');
- Assert.IsTrue(AccountWizardPage.GoToKey(Enum::"File System Connector"::"Test File System Connector"), 'Test Email connector was not shown in the page');
+ Assert.IsTrue(AccountWizardPage.GoToKey(Enum::"File System Connector"::"Test File System Connector"), 'Test File connector was not shown in the page');
// [WHEN] The Name field is drilled down
AccountWizardPage.Next.Invoke();
// [THEN] The Connector registers the Account and the last page is shown
- Assert.AreEqual(AccountWizardPage.EmailAddressfield.Value(), 'Test email address', 'A different Email address was expected');
Assert.AreEqual(AccountWizardPage.NameField.Value(), 'Test account', 'A different name was expected');
Assert.AreEqual(AccountWizardPage.DefaultField.AsBoolean(), true, 'Default should be set to true if it''s the first account to be set up');
end;
@@ -141,7 +120,7 @@ codeunit 134686 "File Accounts Test"
AccountsPage: TestPage "File Accounts";
begin
// [SCENARIO] The add Account action open the Account Wizard page in modal mode
- PermissionsMock.Set('Email Admin');
+ PermissionsMock.Set('File System Admin');
AccountsPage.OpenView();
// [WHEN] The AddAccount action is invoked
@@ -150,118 +129,45 @@ codeunit 134686 "File Accounts Test"
// Verify with AddAccountModalPageHandler
end;
- [Test]
- procedure OpenEditorFromAccountsPageTest()
- var
- TempAccount: Record "File Account" temporary;
- ConnectorMock: Codeunit "Connector Mock";
- Accounts: TestPage "File Accounts";
- Editor: TestPage "Email Editor";
- begin
- // [SCENARIO] Email editor page can be opened from the Accounts page
- Editor.Trap();
- // [GIVEN] A connector is installed and an account is added
- ConnectorMock.Initialize();
- ConnectorMock.AddAccount(TempAccount);
-
- PermissionsMock.Set('Email Edit');
-
- // [WHEN] The Send Email action is invoked
- Accounts.OpenView();
- Accounts.GoToKey(TempAccount."Account Id", TempAccount.Connector);
- Accounts.SendEmail.Invoke();
-
- // [THEN] The Editor page opens to create a new message
- Assert.AreEqual(StrSubstNo(AccountNameLbl, TempAccount.Name, TempAccount."Email Address"), Editor.Account.Value(), 'A different from was expected.');
- end;
-
- [Test]
- procedure OpenSentMailsFromAccountsPageTest()
- var
- TempAccount: Record "File Account" temporary;
- ConnectorMock: Codeunit "Connector Mock";
- Accounts: TestPage "File Accounts";
- SentEmails: TestPage "Sent Emails";
- begin
- // [SCENARIO] Sent emails page can be opened from the Accounts page
- SentEmails.Trap();
- // [GIVEN] A connector is installed and an account is added
- ConnectorMock.Initialize();
- ConnectorMock.AddAccount(TempAccount);
-
- PermissionsMock.Set('Email Edit');
-
- // [WHEN] The Sent Emails action is invoked
- Accounts.OpenView();
- Accounts.SentEmails.Invoke();
-
- // [THEN] The sent emails page opens
- // Verify with Trap
- end;
-
- [Test]
- procedure OpenOutBoxFromAccountsPageTest()
- var
- TempAccount: Record "File Account" temporary;
- ConnectorMock: Codeunit "Connector Mock";
- Accounts: TestPage "File Accounts";
- Outbox: TestPage "Email Outbox";
- begin
- // [SCENARIO] Outbox page can be opened from the Accounts page
- Outbox.Trap();
- // [GIVEN] A connector is installed and an account is added
- ConnectorMock.Initialize();
- ConnectorMock.AddAccount(TempAccount);
-
- PermissionsMock.Set('Email Edit');
-
- // [WHEN] The Outbox action is invoked
- Accounts.OpenView();
- Accounts.Outbox.Invoke();
-
- // [THEN] The outbox page opens
- // Verify with Trap
- end;
-
[Test]
procedure GetAllAccountsTest()
var
- EmailAccountBuffer, EmailAccounts : Record "File Account";
+ FileAccountBuffer, FileAccounts : Record "File Account";
ConnectorMock: Codeunit "Connector Mock";
- EmailAccount: Codeunit "File Account";
+ FileAccount: Codeunit "File Account";
begin
// [SCENARIO] GetAllAccounts retrieves all the registered accounts
// [GIVEN] A connector is installed and no account is added
ConnectorMock.Initialize();
- PermissionsMock.Set('Email Edit');
+ PermissionsMock.Set('File System Edit');
// [WHEN] GetAllAccounts is called
- EmailAccount.GetAllAccounts(EmailAccounts);
+ FileAccount.GetAllAccounts(FileAccounts);
// [THEN] The returned record is empty (there are no registered accounts)
- Assert.IsTrue(EmailAccounts.IsEmpty(), 'Record should be empty');
+ Assert.IsTrue(FileAccounts.IsEmpty(), 'Record should be empty');
// [GIVEN] An account is added to the connector
- ConnectorMock.AddAccount(EmailAccountBuffer);
+ ConnectorMock.AddAccount(FileAccountBuffer);
// [WHEN] GetAllAccounts is called
- EmailAccount.GetAllAccounts(EmailAccounts);
+ FileAccount.GetAllAccounts(FileAccounts);
// [THEN] The returned record is not empty and the values are as expected
- Assert.AreEqual(1, EmailAccounts.Count(), 'Record should not be empty');
- EmailAccounts.FindFirst();
- Assert.AreEqual(EmailAccountBuffer."Account Id", EmailAccounts."Account Id", 'Wrong account ID');
- Assert.AreEqual(Enum::"File System Connector"::"Test File System Connector", EmailAccounts.Connector, 'Wrong connector');
- Assert.AreEqual(EmailAccountBuffer.Name, EmailAccounts.Name, 'Wrong account name');
+ Assert.AreEqual(1, FileAccounts.Count(), 'Record should not be empty');
+ FileAccounts.FindFirst();
+ Assert.AreEqual(FileAccountBuffer."Account Id", FileAccounts."Account Id", 'Wrong account ID');
+ Assert.AreEqual(Enum::"File System Connector"::"Test File System Connector", FileAccounts.Connector, 'Wrong connector');
+ Assert.AreEqual(FileAccountBuffer.Name, FileAccounts.Name, 'Wrong account name');
end;
[Test]
procedure IsAnyAccountRegisteredTest()
var
ConnectorMock: Codeunit "Connector Mock";
- EmailAccount: Codeunit "File Account";
+ FileAccount: Codeunit "File Account";
AccountId: Guid;
begin
// [SCENARIO] File Account Exists works as expected
@@ -269,18 +175,18 @@ codeunit 134686 "File Accounts Test"
// [GIVEN] A connector is installed and no account is added
ConnectorMock.Initialize();
- PermissionsMock.Set('Email Edit');
+ PermissionsMock.Set('File System Edit');
// [WHEN] Calling IsAnyAccountRegistered
// [THEN] it evaluates to false
- Assert.IsFalse(EmailAccount.IsAnyAccountRegistered(), 'There should be no registered accounts');
+ Assert.IsFalse(FileAccount.IsAnyAccountRegistered(), 'There should be no registered accounts');
// [WHEN] An File account is added
ConnectorMock.AddAccount(AccountId);
// [WHEN] Calling IsAnyAccountRegistered
// [THEN] it evaluates to true
- Assert.IsTrue(EmailAccount.IsAnyAccountRegistered(), 'There should be a registered account');
+ Assert.IsTrue(FileAccount.IsAnyAccountRegistered(), 'There should be a registered account');
end;
[Test]
@@ -288,12 +194,12 @@ codeunit 134686 "File Accounts Test"
procedure DeleteAllAccountsTest()
var
ConnectorMock: Codeunit "Connector Mock";
- EmailAccountsSelectionMock: Codeunit "File System Acc Selection Mock";
+ FileAccountsSelectionMock: Codeunit "File System Acc Selection Mock";
FirstAccountId, SecondAccountId, ThirdAccountId : Guid;
- EmailAccountsTestPage: TestPage "File Accounts";
+ FileAccountsTestPage: TestPage "File Accounts";
begin
// [SCENARIO] When all accounts are deleted, the File Accounts page is empty
- PermissionsMock.Set('Email Admin');
+ PermissionsMock.Set('File System Admin');
// [GIVEN] A connector is installed and three account are added
ConnectorMock.Initialize();
@@ -302,19 +208,19 @@ codeunit 134686 "File Accounts Test"
ConnectorMock.AddAccount(ThirdAccountId);
// [WHEN] Open the File Accounts page
- EmailAccountsTestPage.OpenView();
+ FileAccountsTestPage.OpenView();
// [WHEN] Select all of the accounts
- BindSubscription(EmailAccountsSelectionMock);
- EmailAccountsSelectionMock.SelectAccount(FirstAccountId);
- EmailAccountsSelectionMock.SelectAccount(SecondAccountId);
- EmailAccountsSelectionMock.SelectAccount(ThirdAccountId);
+ BindSubscription(FileAccountsSelectionMock);
+ FileAccountsSelectionMock.SelectAccount(FirstAccountId);
+ FileAccountsSelectionMock.SelectAccount(SecondAccountId);
+ FileAccountsSelectionMock.SelectAccount(ThirdAccountId);
// [WHEN] Delete action is invoked and the action is confirmed (see ConfirmYesHandler)
- EmailAccountsTestPage.Delete.Invoke();
+ FileAccountsTestPage.Delete.Invoke();
// [THEN] The page is empty
- Assert.IsFalse(EmailAccountsTestPage.First(), 'The File Accounts page should be empty');
+ Assert.IsFalse(FileAccountsTestPage.First(), 'The File Accounts page should be empty');
end;
[Test]
@@ -322,12 +228,12 @@ codeunit 134686 "File Accounts Test"
procedure DeleteAllAccountsCancelTest()
var
ConnectorMock: Codeunit "Connector Mock";
- EmailAccountsSelectionMock: Codeunit "File System Acc Selection Mock";
+ FileAccountsSelectionMock: Codeunit "File System Acc Selection Mock";
FirstAccountId, SecondAccountId, ThirdAccountId : Guid;
- EmailAccountsTestPage: TestPage "File Accounts";
+ FileAccountsTestPage: TestPage "File Accounts";
begin
// [SCENARIO] When all accounts are about to be deleted but the action in canceled, the File Accounts page contains all of them.
- PermissionsMock.Set('Email Admin');
+ PermissionsMock.Set('File System Admin');
// [GIVEN] A connector is installed and three account are added
ConnectorMock.Initialize();
@@ -336,21 +242,21 @@ codeunit 134686 "File Accounts Test"
ConnectorMock.AddAccount(ThirdAccountId);
// [WHEN] Open the File Accounts page
- EmailAccountsTestPage.OpenView();
+ FileAccountsTestPage.OpenView();
// [WHEN] Select all of the accounts
- BindSubscription(EmailAccountsSelectionMock);
- EmailAccountsSelectionMock.SelectAccount(FirstAccountId);
- EmailAccountsSelectionMock.SelectAccount(SecondAccountId);
- EmailAccountsSelectionMock.SelectAccount(ThirdAccountId);
+ BindSubscription(FileAccountsSelectionMock);
+ FileAccountsSelectionMock.SelectAccount(FirstAccountId);
+ FileAccountsSelectionMock.SelectAccount(SecondAccountId);
+ FileAccountsSelectionMock.SelectAccount(ThirdAccountId);
// [WHEN] Delete action is invoked and the action is not confirmed (see ConfirmNoHandler)
- EmailAccountsTestPage.Delete.Invoke();
+ FileAccountsTestPage.Delete.Invoke();
// [THEN] All of the accounts are on the page
- Assert.IsTrue(EmailAccountsTestPage.GoToKey(FirstAccountId, Enum::"File System Connector"::"Test File System Connector"), 'The first File account should be on the page');
- Assert.IsTrue(EmailAccountsTestPage.GoToKey(SecondAccountId, Enum::"File System Connector"::"Test File System Connector"), 'The second File account should be on the page');
- Assert.IsTrue(EmailAccountsTestPage.GoToKey(ThirdAccountId, Enum::"File System Connector"::"Test File System Connector"), 'The third File account should be on the page');
+ Assert.IsTrue(FileAccountsTestPage.GoToKey(FirstAccountId, Enum::"File System Connector"::"Test File System Connector"), 'The first File account should be on the page');
+ Assert.IsTrue(FileAccountsTestPage.GoToKey(SecondAccountId, Enum::"File System Connector"::"Test File System Connector"), 'The second File account should be on the page');
+ Assert.IsTrue(FileAccountsTestPage.GoToKey(ThirdAccountId, Enum::"File System Connector"::"Test File System Connector"), 'The third File account should be on the page');
end;
[Test]
@@ -358,12 +264,12 @@ codeunit 134686 "File Accounts Test"
procedure DeleteSomeAccountsTest()
var
ConnectorMock: Codeunit "Connector Mock";
- EmailAccountsSelectionMock: Codeunit "File System Acc Selection Mock";
+ FileAccountsSelectionMock: Codeunit "File System Acc Selection Mock";
FirstAccountId, SecondAccountId, ThirdAccountId : Guid;
- EmailAccountsTestPage: TestPage "File Accounts";
+ FileAccountsTestPage: TestPage "File Accounts";
begin
// [SCENARIO] When some accounts are deleted, they cannot be found on the page
- PermissionsMock.Set('Email Admin');
+ PermissionsMock.Set('File System Admin');
// [GIVEN] A connector is installed and three account are added
ConnectorMock.Initialize();
@@ -372,20 +278,20 @@ codeunit 134686 "File Accounts Test"
ConnectorMock.AddAccount(ThirdAccountId);
// [WHEN] Open the File Accounts page
- EmailAccountsTestPage.OpenView();
+ FileAccountsTestPage.OpenView();
// [WHEN] Select only two of the accounts
- BindSubscription(EmailAccountsSelectionMock);
- EmailAccountsSelectionMock.SelectAccount(FirstAccountId);
- EmailAccountsSelectionMock.SelectAccount(ThirdAccountId);
+ BindSubscription(FileAccountsSelectionMock);
+ FileAccountsSelectionMock.SelectAccount(FirstAccountId);
+ FileAccountsSelectionMock.SelectAccount(ThirdAccountId);
// [WHEN] Delete action is invoked and the action is confirmed (see ConfirmYesHandler)
- EmailAccountsTestPage.Delete.Invoke();
+ FileAccountsTestPage.Delete.Invoke();
// [THEN] The deleted accounts are not on the page, the non-deleted accounts are on the page.
- Assert.IsFalse(EmailAccountsTestPage.GoToKey(FirstAccountId, Enum::"File System Connector"::"Test File System Connector"), 'The first File account should not be on the page');
- Assert.IsTrue(EmailAccountsTestPage.GoToKey(SecondAccountId, Enum::"File System Connector"::"Test File System Connector"), 'The second File account should be on the page');
- Assert.IsFalse(EmailAccountsTestPage.GoToKey(ThirdAccountId, Enum::"File System Connector"::"Test File System Connector"), 'The third File account should not be on the page');
+ Assert.IsFalse(FileAccountsTestPage.GoToKey(FirstAccountId, Enum::"File System Connector"::"Test File System Connector"), 'The first File account should not be on the page');
+ Assert.IsTrue(FileAccountsTestPage.GoToKey(SecondAccountId, Enum::"File System Connector"::"Test File System Connector"), 'The second File account should be on the page');
+ Assert.IsFalse(FileAccountsTestPage.GoToKey(ThirdAccountId, Enum::"File System Connector"::"Test File System Connector"), 'The third File account should not be on the page');
end;
[Test]
@@ -394,13 +300,13 @@ codeunit 134686 "File Accounts Test"
var
SecondAccount: Record "File Account";
ConnectorMock: Codeunit "Connector Mock";
- EmailAccountsSelectionMock: Codeunit "File System Acc Selection Mock";
- EmailScenario: Codeunit "File Scenario";
+ FileAccountsSelectionMock: Codeunit "File System Acc Selection Mock";
+ FileScenario: Codeunit "File Scenario";
FirstAccountId, ThirdAccountId : Guid;
- EmailAccountsTestPage: TestPage "File Accounts";
+ FileAccountsTestPage: TestPage "File Accounts";
begin
// [SCENARIO] When the a non default account is deleted, the user is not prompted to choose a new default account.
- PermissionsMock.Set('Email Admin');
+ PermissionsMock.Set('File System Admin');
// [GIVEN] A connector is installed and three account are added
ConnectorMock.Initialize();
@@ -409,26 +315,26 @@ codeunit 134686 "File Accounts Test"
ConnectorMock.AddAccount(ThirdAccountId);
// [GIVEN] The second account is set as default
- EmailScenario.SetDefaultFileAccount(SecondAccount);
+ FileScenario.SetDefaultFileAccount(SecondAccount);
// [WHEN] Open the File Accounts page
- EmailAccountsTestPage.OpenView();
+ FileAccountsTestPage.OpenView();
// [WHEN] Select a non-default account
- BindSubscription(EmailAccountsSelectionMock);
- EmailAccountsSelectionMock.SelectAccount(FirstAccountId);
+ BindSubscription(FileAccountsSelectionMock);
+ FileAccountsSelectionMock.SelectAccount(FirstAccountId);
// [WHEN] Delete action is invoked and the action is confirmed (see ConfirmYesHandler)
- EmailAccountsTestPage.Delete.Invoke();
+ FileAccountsTestPage.Delete.Invoke();
// [THEN] The deleted accounts are not on the page, the non-deleted accounts are on the page.
- Assert.IsFalse(EmailAccountsTestPage.GoToKey(FirstAccountId, Enum::"File System Connector"::"Test File System Connector"), 'The first File account should not be on the page');
+ Assert.IsFalse(FileAccountsTestPage.GoToKey(FirstAccountId, Enum::"File System Connector"::"Test File System Connector"), 'The first File account should not be on the page');
- Assert.IsTrue(EmailAccountsTestPage.GoToKey(SecondAccount."Account Id", Enum::"File System Connector"::"Test File System Connector"), 'The second File account should be on the page');
- Assert.IsTrue(GetDefaultFieldValueAsBoolean(EmailAccountsTestPage.DefaultField.Value), 'The second account should be marked as default');
+ Assert.IsTrue(FileAccountsTestPage.GoToKey(SecondAccount."Account Id", Enum::"File System Connector"::"Test File System Connector"), 'The second File account should be on the page');
+ Assert.IsTrue(GetDefaultFieldValueAsBoolean(FileAccountsTestPage.DefaultField.Value), 'The second account should be marked as default');
- Assert.IsTrue(EmailAccountsTestPage.GoToKey(ThirdAccountId, Enum::"File System Connector"::"Test File System Connector"), 'The third File account should be on the page');
- Assert.IsFalse(GetDefaultFieldValueAsBoolean(EmailAccountsTestPage.DefaultField.Value), 'The third account should not be marked as default');
+ Assert.IsTrue(FileAccountsTestPage.GoToKey(ThirdAccountId, Enum::"File System Connector"::"Test File System Connector"), 'The third File account should be on the page');
+ Assert.IsFalse(GetDefaultFieldValueAsBoolean(FileAccountsTestPage.DefaultField.Value), 'The third account should not be marked as default');
end;
[Test]
@@ -437,13 +343,13 @@ codeunit 134686 "File Accounts Test"
var
SecondAccount: Record "File Account";
ConnectorMock: Codeunit "Connector Mock";
- EmailAccountsSelectionMock: Codeunit "File System Acc Selection Mock";
- EmailScenario: Codeunit "File Scenario";
+ FileAccountsSelectionMock: Codeunit "File System Acc Selection Mock";
+ FileScenario: Codeunit "File Scenario";
FirstAccountId, ThirdAccountId : Guid;
- EmailAccountsTestPage: TestPage "File Accounts";
+ FileAccountsTestPage: TestPage "File Accounts";
begin
// [SCENARIO] When the default account is deleted, the user is not prompted to choose a new default account if there's only one account left
- PermissionsMock.Set('Email Admin');
+ PermissionsMock.Set('File System Admin');
// [GIVEN] A connector is installed and three account are added
ConnectorMock.Initialize();
@@ -452,25 +358,25 @@ codeunit 134686 "File Accounts Test"
ConnectorMock.AddAccount(ThirdAccountId);
// [GIVEN] The second account is set as default
- EmailScenario.SetDefaultFileAccount(SecondAccount);
+ FileScenario.SetDefaultFileAccount(SecondAccount);
// [WHEN] Open the File Accounts page
- EmailAccountsTestPage.OpenView();
+ FileAccountsTestPage.OpenView();
// [WHEN] Select accounts including the default one
- BindSubscription(EmailAccountsSelectionMock);
- EmailAccountsSelectionMock.SelectAccount(SecondAccount."Account Id");
- EmailAccountsSelectionMock.SelectAccount(ThirdAccountId);
+ BindSubscription(FileAccountsSelectionMock);
+ FileAccountsSelectionMock.SelectAccount(SecondAccount."Account Id");
+ FileAccountsSelectionMock.SelectAccount(ThirdAccountId);
// [WHEN] Delete action is invoked and the action is confirmed (see ConfirmYesHandler)
- EmailAccountsTestPage.Delete.Invoke();
+ FileAccountsTestPage.Delete.Invoke();
// [THEN] The deleted accounts are not on the page, the non-deleted accounts are on the page.
- Assert.IsTrue(EmailAccountsTestPage.GoToKey(FirstAccountId, Enum::"File System Connector"::"Test File System Connector"), 'The first File account should be on the page');
- Assert.IsTrue(GetDefaultFieldValueAsBoolean(EmailAccountsTestPage.DefaultField.Value), 'The first account should be marked as default');
+ Assert.IsTrue(FileAccountsTestPage.GoToKey(FirstAccountId, Enum::"File System Connector"::"Test File System Connector"), 'The first File account should be on the page');
+ Assert.IsTrue(GetDefaultFieldValueAsBoolean(FileAccountsTestPage.DefaultField.Value), 'The first account should be marked as default');
- Assert.IsFalse(EmailAccountsTestPage.GoToKey(SecondAccount."Account Id", Enum::"File System Connector"::"Test File System Connector"), 'The second File account should not be on the page');
- Assert.IsFalse(EmailAccountsTestPage.GoToKey(ThirdAccountId, Enum::"File System Connector"::"Test File System Connector"), 'The third File account should not be on the page');
+ Assert.IsFalse(FileAccountsTestPage.GoToKey(SecondAccount."Account Id", Enum::"File System Connector"::"Test File System Connector"), 'The second File account should not be on the page');
+ Assert.IsFalse(FileAccountsTestPage.GoToKey(ThirdAccountId, Enum::"File System Connector"::"Test File System Connector"), 'The third File account should not be on the page');
end;
[Test]
@@ -479,13 +385,13 @@ codeunit 134686 "File Accounts Test"
var
SecondAccount: Record "File Account";
ConnectorMock: Codeunit "Connector Mock";
- EmailAccountsSelectionMock: Codeunit "File System Acc Selection Mock";
- EmailScenario: Codeunit "File Scenario";
+ FileAccountsSelectionMock: Codeunit "File System Acc Selection Mock";
+ FileScenario: Codeunit "File Scenario";
FirstAccountId, ThirdAccountId : Guid;
- EmailAccountsTestPage: TestPage "File Accounts";
+ FileAccountsTestPage: TestPage "File Accounts";
begin
// [SCENARIO] When the default account is deleted, the user is prompted to choose a new default account but they cancel.
- PermissionsMock.Set('Email Admin');
+ PermissionsMock.Set('File System Admin');
// [GIVEN] A connector is installed and three account are added
ConnectorMock.Initialize();
@@ -494,27 +400,27 @@ codeunit 134686 "File Accounts Test"
ConnectorMock.AddAccount(ThirdAccountId);
// [GIVEN] The second account is set as default
- EmailScenario.SetDefaultFileAccount(SecondAccount);
+ FileScenario.SetDefaultFileAccount(SecondAccount);
// [WHEN] Open the File Accounts page
- EmailAccountsTestPage.OpenView();
+ FileAccountsTestPage.OpenView();
// [WHEN] Select the default account
- BindSubscription(EmailAccountsSelectionMock);
- EmailAccountsSelectionMock.SelectAccount(SecondAccount."Account Id");
+ BindSubscription(FileAccountsSelectionMock);
+ FileAccountsSelectionMock.SelectAccount(SecondAccount."Account Id");
// [WHEN] Delete action is invoked and the action is confirmed (see ConfirmYesHandler)
AccountToSelect := ThirdAccountId; // The third account is selected as the new default account
- EmailAccountsTestPage.Delete.Invoke();
+ FileAccountsTestPage.Delete.Invoke();
// [THEN] The default account was deleted and there is no new default account
- Assert.IsTrue(EmailAccountsTestPage.GoToKey(FirstAccountId, Enum::"File System Connector"::"Test File System Connector"), 'The first File account should be on the page');
- Assert.IsFalse(GetDefaultFieldValueAsBoolean(EmailAccountsTestPage.DefaultField.Value), 'The third account should not be marked as default');
+ Assert.IsTrue(FileAccountsTestPage.GoToKey(FirstAccountId, Enum::"File System Connector"::"Test File System Connector"), 'The first File account should be on the page');
+ Assert.IsFalse(GetDefaultFieldValueAsBoolean(FileAccountsTestPage.DefaultField.Value), 'The third account should not be marked as default');
- Assert.IsFalse(EmailAccountsTestPage.GoToKey(SecondAccount."Account Id", Enum::"File System Connector"::"Test File System Connector"), 'The second File account should not be on the page');
+ Assert.IsFalse(FileAccountsTestPage.GoToKey(SecondAccount."Account Id", Enum::"File System Connector"::"Test File System Connector"), 'The second File account should not be on the page');
- Assert.IsTrue(EmailAccountsTestPage.GoToKey(ThirdAccountId, Enum::"File System Connector"::"Test File System Connector"), 'The third File account should be on the page');
- Assert.IsFalse(GetDefaultFieldValueAsBoolean(EmailAccountsTestPage.DefaultField.Value), 'The third account should not be marked as default');
+ Assert.IsTrue(FileAccountsTestPage.GoToKey(ThirdAccountId, Enum::"File System Connector"::"Test File System Connector"), 'The third File account should be on the page');
+ Assert.IsFalse(GetDefaultFieldValueAsBoolean(FileAccountsTestPage.DefaultField.Value), 'The third account should not be marked as default');
end;
[Test]
@@ -523,13 +429,13 @@ codeunit 134686 "File Accounts Test"
var
SecondAccount: Record "File Account";
ConnectorMock: Codeunit "Connector Mock";
- EmailAccountsSelectionMock: Codeunit "File System Acc Selection Mock";
- EmailScenario: Codeunit "File Scenario";
+ FileAccountsSelectionMock: Codeunit "File System Acc Selection Mock";
+ FileScenario: Codeunit "File Scenario";
FirstAccountId, ThirdAccountId : Guid;
- EmailAccountsTestPage: TestPage "File Accounts";
+ FileAccountsTestPage: TestPage "File Accounts";
begin
// [SCENARIO] When the default account is deleted, the user is prompted to choose a new default account
- PermissionsMock.Set('Email Admin');
+ PermissionsMock.Set('File System Admin');
// [GIVEN] A connector is installed and three account are added
ConnectorMock.Initialize();
@@ -538,71 +444,32 @@ codeunit 134686 "File Accounts Test"
ConnectorMock.AddAccount(ThirdAccountId);
// [GIVEN] The second account is set as default
- EmailScenario.SetDefaultFileAccount(SecondAccount);
+ FileScenario.SetDefaultFileAccount(SecondAccount);
// [WHEN] Open the File Accounts page
- EmailAccountsTestPage.OpenView();
+ FileAccountsTestPage.OpenView();
// [WHEN] Select the default account
- BindSubscription(EmailAccountsSelectionMock);
- EmailAccountsSelectionMock.SelectAccount(SecondAccount."Account Id");
+ BindSubscription(FileAccountsSelectionMock);
+ FileAccountsSelectionMock.SelectAccount(SecondAccount."Account Id");
// [WHEN] Delete action is invoked and the action is confirmed (see ConfirmYesHandler)
AccountToSelect := ThirdAccountId; // The third account is selected as the new default account
- EmailAccountsTestPage.Delete.Invoke();
+ FileAccountsTestPage.Delete.Invoke();
// [THEN] The second account is not on the page, the third account is set as default
- Assert.IsTrue(EmailAccountsTestPage.GoToKey(FirstAccountId, Enum::"File System Connector"::"Test File System Connector"), 'The first File account should be on the page');
- Assert.IsFalse(GetDefaultFieldValueAsBoolean(EmailAccountsTestPage.DefaultField.Value), 'The first account should not be marked as default');
-
- Assert.IsFalse(EmailAccountsTestPage.GoToKey(SecondAccount."Account Id", Enum::"File System Connector"::"Test File System Connector"), 'The second File account should not be on the page');
-
- Assert.IsTrue(EmailAccountsTestPage.GoToKey(ThirdAccountId, Enum::"File System Connector"::"Test File System Connector"), 'The third File account should be on the page');
- Assert.IsTrue(GetDefaultFieldValueAsBoolean(EmailAccountsTestPage.DefaultField.Value), 'The third account should be marked as default');
- end;
-
- [Test]
- procedure DeleteAllAccountsWithoutUITest()
- var
- TempEmailAccount: Record "File Account" temporary;
- TempEmailAccountToDelete: Record "File Account" temporary;
- ConnectorMock: Codeunit "Connector Mock";
- EmailAccount: Codeunit "File Account";
- FirstAccountId, SecondAccountId : Guid;
- begin
- // [SCENARIO] When all accounts are deleted, the File Accounts page is empty
- PermissionsMock.Set('Email Admin');
-
- // [GIVEN] A connector is installed and two account are added
- ConnectorMock.Initialize();
- ConnectorMock.AddAccount(FirstAccountId);
- ConnectorMock.AddAccount(SecondAccountId);
+ Assert.IsTrue(FileAccountsTestPage.GoToKey(FirstAccountId, Enum::"File System Connector"::"Test File System Connector"), 'The first File account should be on the page');
+ Assert.IsFalse(GetDefaultFieldValueAsBoolean(FileAccountsTestPage.DefaultField.Value), 'The first account should not be marked as default');
- // [GIVEN] Mark first account for deletion
- EmailAccount.GetAllAccounts(TempEmailAccountToDelete);
- Assert.AreEqual(2, TempEmailAccountToDelete.Count(), 'Expected to have 2 accounts.');
- TempEmailAccountToDelete.SetRange("Account Id", FirstAccountId);
+ Assert.IsFalse(FileAccountsTestPage.GoToKey(SecondAccount."Account Id", Enum::"File System Connector"::"Test File System Connector"), 'The second File account should not be on the page');
- // [WHEN] File Accounts are deleted
- EmailAccount.DeleteAccounts(TempEmailAccountToDelete, true);
-
- // [THEN] Verify second account still exists
- EmailAccount.GetAllAccounts(TempEmailAccount);
- Assert.AreEqual(1, TempEmailAccount.Count(), 'Expected to have 1 account.');
- TempEmailAccount.FindFirst();
- Assert.AreEqual(SecondAccountId, TempEmailAccount."Account Id", 'The second File account should still exist.');
+ Assert.IsTrue(FileAccountsTestPage.GoToKey(ThirdAccountId, Enum::"File System Connector"::"Test File System Connector"), 'The third File account should be on the page');
+ Assert.IsTrue(GetDefaultFieldValueAsBoolean(FileAccountsTestPage.DefaultField.Value), 'The third account should be marked as default');
end;
[ModalPageHandler]
procedure AddAccountModalPageHandler(var AccountWizardTestPage: TestPage "File Account Wizard")
begin
-
- end;
-
- [PageHandler]
- procedure SentEmailsPageHandler(var SentEmailsPage: TestPage "Sent Emails")
- begin
-
end;
[ModalPageHandler]
@@ -611,7 +478,6 @@ codeunit 134686 "File Accounts Test"
AccountsPage.Cancel().Invoke();
end;
-
[ModalPageHandler]
procedure ChooseNewDefaultAccountHandler(var AccountsPage: TestPage "File Accounts")
begin
diff --git a/src/System Application/Test/File System/src/FileScenarioPageTest.Codeunit.al b/src/System Application/Test/File System/src/FileScenarioPageTest.Codeunit.al
index c38af682b1..c93b0dc990 100644
--- a/src/System Application/Test/File System/src/FileScenarioPageTest.Codeunit.al
+++ b/src/System Application/Test/File System/src/FileScenarioPageTest.Codeunit.al
@@ -17,7 +17,7 @@ codeunit 134695 "File Scenario Page Test"
var
Assert: Codeunit "Library Assert";
ConnectorMock: Codeunit "Connector Mock";
- EmailScenarioMock: Codeunit "File Scenario Mock";
+ FileScenarioMock: Codeunit "File Scenario Mock";
PermissionsMock: Codeunit "Permissions Mock";
DisplayNameTxt: Label '%1', Locked = true;
@@ -29,10 +29,10 @@ codeunit 134695 "File Scenario Page Test"
var
FileScenarioPage: TestPage "File Scenario Setup";
begin
- // [Scenario] The "Email Scenario Setup" shows no data when there are no email accounts
- PermissionsMock.Set('Email Admin');
+ // [Scenario] The "File Scenario Setup" shows no data when there are no file accounts
+ PermissionsMock.Set('File System Admin');
- // [Given] No email account is registered.
+ // [Given] No file account is registered.
ConnectorMock.Initialize();
// [When] Opening the the page
@@ -51,10 +51,10 @@ codeunit 134695 "File Scenario Page Test"
FileAccount: Record "File Account";
FileScenarioPage: TestPage "File Scenario Setup";
begin
- // [Scenario] The "Email Scenario Setup" shows one entry when there is only one email account and no scenarios
- PermissionsMock.Set('File Admin');
+ // [Scenario] The "File Scenario Setup" shows one entry when there is only one file account and no scenarios
+ PermissionsMock.Set('File System Admin');
- // [Given] One email account is registered.
+ // [Given] One file account is registered.
ConnectorMock.Initialize();
ConnectorMock.AddAccount(FileAccount);
@@ -81,36 +81,36 @@ codeunit 134695 "File Scenario Page Test"
[Scope('OnPrem')]
procedure PageOpenOneDefaultEntryTest()
var
- EmailAccount: Record "File Account";
- EmailScenarioPage: TestPage "File Scenario Setup";
+ FileAccount: Record "File Account";
+ FileScenarioPage: TestPage "File Scenario Setup";
begin
- // [Scenario] The "Email Scenario Setup" shows one entry when there is only one email account and no scenarios
- PermissionsMock.Set('File Admin');
+ // [Scenario] The "File Scenario Setup" shows one entry when there is only one file account and no scenarios
+ PermissionsMock.Set('File System Admin');
- // [Given] One email account is registered and it's set as default.
+ // [Given] One file account is registered and it's set as default.
ConnectorMock.Initialize();
- ConnectorMock.AddAccount(EmailAccount);
+ ConnectorMock.AddAccount(FileAccount);
- EmailScenarioMock.DeleteAllMappings();
- EmailScenarioMock.AddMapping(Enum::"File Scenario"::Default, EmailAccount."Account Id", EmailAccount.Connector);
+ FileScenarioMock.DeleteAllMappings();
+ FileScenarioMock.AddMapping(Enum::"File Scenario"::Default, FileAccount."Account Id", FileAccount.Connector);
// [When] Opening the the page
- EmailScenarioPage.Trap();
- EmailScenarioPage.OpenView();
+ FileScenarioPage.Trap();
+ FileScenarioPage.OpenView();
// [Then] There is one entry on the page and it is set as default
- Assert.IsTrue(EmailScenarioPage.First(), 'There should be an entry on the page');
+ Assert.IsTrue(FileScenarioPage.First(), 'There should be an entry on the page');
// Properties are as expected
- Assert.AreEqual(StrSubstNo(DisplayNameTxt, EmailAccount.Name), EmailScenarioPage.Name.Value, 'Wrong entry name');
- Assert.IsTrue(GetDefaultFieldValueAsBoolean(EmailScenarioPage.Default.Value), 'The account should be marked as default');
+ Assert.AreEqual(StrSubstNo(DisplayNameTxt, FileAccount.Name), FileScenarioPage.Name.Value, 'Wrong entry name');
+ Assert.IsTrue(GetDefaultFieldValueAsBoolean(FileScenarioPage.Default.Value), 'The account should be marked as default');
// Actions visibility is as expected
- Assert.IsTrue(EmailScenarioPage.AddScenario.Visible(), 'The action "Add Scenarios" should be visible');
- Assert.IsFalse(EmailScenarioPage.ChangeAccount.Visible(), 'The action "Change Accounts" should not be visible');
- Assert.IsFalse(EmailScenarioPage.Unassign.Visible(), 'The action "Unassign" should not be visible');
+ Assert.IsTrue(FileScenarioPage.AddScenario.Visible(), 'The action "Add Scenarios" should be visible');
+ Assert.IsFalse(FileScenarioPage.ChangeAccount.Visible(), 'The action "Change Accounts" should not be visible');
+ Assert.IsFalse(FileScenarioPage.Unassign.Visible(), 'The action "Unassign" should not be visible');
- Assert.IsFalse(EmailScenarioPage.Next(), 'There should not be another entry on the page');
+ Assert.IsFalse(FileScenarioPage.Next(), 'There should not be another entry on the page');
end;
@@ -119,47 +119,47 @@ codeunit 134695 "File Scenario Page Test"
[TransactionModel(TransactionModel::AutoRollback)]
procedure PageOpenOneAcountsTwoScenariosTest()
var
- EmailAccount: Record "File Account";
- EmailScenarioPage: TestPage "File Scenario Setup";
+ FileAccount: Record "File Account";
+ FileScenarioPage: TestPage "File Scenario Setup";
begin
- // [Scenario] Having one default account with a non-default scenario assigned displays propely on "Email Scenario Setup"
- PermissionsMock.Set('Email Admin');
+ // [Scenario] Having one default account with a non-default scenario assigned displays propely on "File Scenario Setup"
+ PermissionsMock.Set('File System Admin');
- // [Given] One email account is registered and it's set as default.
+ // [Given] One file account is registered and it's set as default.
ConnectorMock.Initialize();
- ConnectorMock.AddAccount(EmailAccount);
+ ConnectorMock.AddAccount(FileAccount);
- EmailScenarioMock.DeleteAllMappings();
- EmailScenarioMock.AddMapping(Enum::"File Scenario"::Default, EmailAccount."Account Id", EmailAccount.Connector);
- EmailScenarioMock.AddMapping(Enum::"File Scenario"::"Test File Scenario", EmailAccount."Account Id", EmailAccount.Connector);
+ FileScenarioMock.DeleteAllMappings();
+ FileScenarioMock.AddMapping(Enum::"File Scenario"::Default, FileAccount."Account Id", FileAccount.Connector);
+ FileScenarioMock.AddMapping(Enum::"File Scenario"::"Test File Scenario", FileAccount."Account Id", FileAccount.Connector);
// [When] Opening the the page
- EmailScenarioPage.Trap();
- EmailScenarioPage.OpenView();
+ FileScenarioPage.Trap();
+ FileScenarioPage.OpenView();
// [Then] There is one entry on the page and it is set as default. There's another entry for the other assigned scenario
- Assert.IsTrue(EmailScenarioPage.First(), 'There should be data on the page');
+ Assert.IsTrue(FileScenarioPage.First(), 'There should be data on the page');
// Properties are as expected
- Assert.AreEqual(StrSubstNo(DisplayNameTxt, EmailAccount.Name), EmailScenarioPage.Name.Value, 'Wrong entry name');
- Assert.IsTrue(GetDefaultFieldValueAsBoolean(EmailScenarioPage.Default.Value), 'The account should be marked as default');
+ Assert.AreEqual(StrSubstNo(DisplayNameTxt, FileAccount.Name), FileScenarioPage.Name.Value, 'Wrong entry name');
+ Assert.IsTrue(GetDefaultFieldValueAsBoolean(FileScenarioPage.Default.Value), 'The account should be marked as default');
// Actions visibility is as expected
- Assert.IsTrue(EmailScenarioPage.AddScenario.Visible(), 'The action "Add Scenarios" should be visible');
- Assert.IsFalse(EmailScenarioPage.ChangeAccount.Visible(), 'The action "Change Accounts" should not be visible');
- Assert.IsFalse(EmailScenarioPage.Unassign.Visible(), 'The action "Unassign" should not be visible');
+ Assert.IsTrue(FileScenarioPage.AddScenario.Visible(), 'The action "Add Scenarios" should be visible');
+ Assert.IsFalse(FileScenarioPage.ChangeAccount.Visible(), 'The action "Change Accounts" should not be visible');
+ Assert.IsFalse(FileScenarioPage.Unassign.Visible(), 'The action "Unassign" should not be visible');
- EmailScenarioPage.Expand(true);
- Assert.IsTrue(EmailScenarioPage.Next(), 'There should be another entry on the page');
+ FileScenarioPage.Expand(true);
+ Assert.IsTrue(FileScenarioPage.Next(), 'There should be another entry on the page');
// Properies are as expected
- Assert.AreEqual(Format(Enum::"File Scenario"::"Test File Scenario"), EmailScenarioPage.Name.Value, 'Wrong entry name');
- Assert.IsFalse(GetDefaultFieldValueAsBoolean(EmailScenarioPage.Default.Value), 'The account should not be marked as default');
+ Assert.AreEqual(Format(Enum::"File Scenario"::"Test File Scenario"), FileScenarioPage.Name.Value, 'Wrong entry name');
+ Assert.IsFalse(GetDefaultFieldValueAsBoolean(FileScenarioPage.Default.Value), 'The account should not be marked as default');
// Actions visibility is as expected
- Assert.IsFalse(EmailScenarioPage.AddScenario.Visible(), 'The action "Add Scenarios" should be visible');
- Assert.IsTrue(EmailScenarioPage.ChangeAccount.Visible(), 'The action "Change Accounts" should not be visible');
- Assert.IsTrue(EmailScenarioPage.Unassign.Visible(), 'The action "Unassign" should not be visible');
+ Assert.IsFalse(FileScenarioPage.AddScenario.Visible(), 'The action "Add Scenarios" should be visible');
+ Assert.IsTrue(FileScenarioPage.ChangeAccount.Visible(), 'The action "Change Accounts" should not be visible');
+ Assert.IsTrue(FileScenarioPage.Unassign.Visible(), 'The action "Unassign" should not be visible');
end;
[Test]
@@ -167,38 +167,38 @@ codeunit 134695 "File Scenario Page Test"
[TransactionModel(TransactionModel::AutoRollback)]
procedure PageOpenTwoAcountsTwoScenariosTest()
var
- FirstEmailAccount, SecondEmailAccount : Record "File Account";
- EmailScenarioPage: TestPage "File Scenario Setup";
+ FirstFileAccount, SecondFileAccount : Record "File Account";
+ FileScenarioPage: TestPage "File Scenario Setup";
begin
- // [Scenario] The "Email Scenario Setup" shows three entries when there are two accounts - one with the default scenario and one with a non-default scenario
- PermissionsMock.Set('Email Admin');
+ // [Scenario] The "File Scenario Setup" shows three entries when there are two accounts - one with the default scenario and one with a non-default scenario
+ PermissionsMock.Set('File System Admin');
- // [Given] Two email accounts are registered. One is set as default.
+ // [Given] Two file accounts are registered. One is set as default.
ConnectorMock.Initialize();
- ConnectorMock.AddAccount(FirstEmailAccount);
- ConnectorMock.AddAccount(SecondEmailAccount);
+ ConnectorMock.AddAccount(FirstFileAccount);
+ ConnectorMock.AddAccount(SecondFileAccount);
- EmailScenarioMock.DeleteAllMappings();
- EmailScenarioMock.AddMapping(Enum::"File Scenario"::Default, FirstEmailAccount."Account Id", FirstEmailAccount.Connector);
- EmailScenarioMock.AddMapping(Enum::"File Scenario"::"Test File Scenario", SecondEmailAccount."Account Id", SecondEmailAccount.Connector);
+ FileScenarioMock.DeleteAllMappings();
+ FileScenarioMock.AddMapping(Enum::"File Scenario"::Default, FirstFileAccount."Account Id", FirstFileAccount.Connector);
+ FileScenarioMock.AddMapping(Enum::"File Scenario"::"Test File Scenario", SecondFileAccount."Account Id", SecondFileAccount.Connector);
// [When] Opening the the page
- EmailScenarioPage.Trap();
- EmailScenarioPage.OpenView();
+ FileScenarioPage.Trap();
+ FileScenarioPage.OpenView();
// [Then] There are three entries on the page. One is set as dedault
- Assert.IsTrue(EmailScenarioPage.GoToKey(-1, FirstEmailAccount."Account Id", FirstEmailAccount.Connector), 'There should be data on the page');
- Assert.AreEqual(StrSubstNo(DisplayNameTxt, FirstEmailAccount.Name), EmailScenarioPage.Name.Value, 'Wrong first entry name');
- Assert.IsTrue(GetDefaultFieldValueAsBoolean(EmailScenarioPage.Default.Value), 'The account should be marked as default');
-
- Assert.IsTrue(EmailScenarioPage.GoToKey(-1, SecondEmailAccount."Account Id", SecondEmailAccount.Connector), 'There should be another entry on the page');
- Assert.AreEqual(StrSubstNo(DisplayNameTxt, SecondEmailAccount.Name), EmailScenarioPage.Name.Value, 'Wrong second entry name');
- Assert.IsFalse(GetDefaultFieldValueAsBoolean(EmailScenarioPage.Default.Value), 'The account should not be marked as default');
-
- EmailScenarioPage.Expand(true);
- Assert.IsTrue(EmailScenarioPage.Next(), 'There should be a third entry on the page');
- Assert.AreEqual(Format(Enum::"File Scenario"::"Test File Scenario"), EmailScenarioPage.Name.Value, 'Wrong third entry name');
- Assert.IsFalse(GetDefaultFieldValueAsBoolean(EmailScenarioPage.Default.Value), 'The account should not be marked as default');
+ Assert.IsTrue(FileScenarioPage.GoToKey(-1, FirstFileAccount."Account Id", FirstFileAccount.Connector), 'There should be data on the page');
+ Assert.AreEqual(StrSubstNo(DisplayNameTxt, FirstFileAccount.Name), FileScenarioPage.Name.Value, 'Wrong first entry name');
+ Assert.IsTrue(GetDefaultFieldValueAsBoolean(FileScenarioPage.Default.Value), 'The account should be marked as default');
+
+ Assert.IsTrue(FileScenarioPage.GoToKey(-1, SecondFileAccount."Account Id", SecondFileAccount.Connector), 'There should be another entry on the page');
+ Assert.AreEqual(StrSubstNo(DisplayNameTxt, SecondFileAccount.Name), FileScenarioPage.Name.Value, 'Wrong second entry name');
+ Assert.IsFalse(GetDefaultFieldValueAsBoolean(FileScenarioPage.Default.Value), 'The account should not be marked as default');
+
+ FileScenarioPage.Expand(true);
+ Assert.IsTrue(FileScenarioPage.Next(), 'There should be a third entry on the page');
+ Assert.AreEqual(Format(Enum::"File Scenario"::"Test File Scenario"), FileScenarioPage.Name.Value, 'Wrong third entry name');
+ Assert.IsFalse(GetDefaultFieldValueAsBoolean(FileScenarioPage.Default.Value), 'The account should not be marked as default');
end;
local procedure GetDefaultFieldValueAsBoolean(DefaultFieldValue: Text): Boolean
diff --git a/src/System Application/Test/File System/src/FileScenarioTest.Codeunit.al b/src/System Application/Test/File System/src/FileScenarioTest.Codeunit.al
index 7a07468254..e53571ef71 100644
--- a/src/System Application/Test/File System/src/FileScenarioTest.Codeunit.al
+++ b/src/System Application/Test/File System/src/FileScenarioTest.Codeunit.al
@@ -30,7 +30,7 @@ codeunit 134693 "File Scenario Test"
FileAccount: Record "File Account";
begin
// [Scenario] When the File scenario isn't mapped an File account, GetFileAccount returns false
- PermissionsMock.Set('File Admin');
+ PermissionsMock.Set('File System Admin');
// [Given] No mappings between Files and scenarios
Initialize();
@@ -48,7 +48,7 @@ codeunit 134693 "File Scenario Test"
NonExistentAccountId: Guid;
begin
// [Scenario] When the File scenario is mapped non-existing File account, GetFileAccount returns false
- PermissionsMock.Set('File Admin');
+ PermissionsMock.Set('File System Admin');
// [Given] An File scenario pointing to a non-existing File account
Initialize();
@@ -68,7 +68,7 @@ codeunit 134693 "File Scenario Test"
NonExistentAccountId: Guid;
begin
// [Scenario] When the default File scenario is mapped to a non-existing File account, GetFileAccount returns false
- PermissionsMock.Set('File Admin');
+ PermissionsMock.Set('File System Admin');
// [Given] An File scenario isn't mapped to a account and the default scenario is mapped to a non-existing account
Initialize();
@@ -88,7 +88,7 @@ codeunit 134693 "File Scenario Test"
AccountId: Guid;
begin
// [Scenario] When the default File scenario is mapped to an existing File account, GetFileAccount returns that account
- PermissionsMock.Set('File Admin');
+ PermissionsMock.Set('File System Admin');
// [Given] An File scenario isn't mapped to an account and the default scenario is mapped to an existing account
Initialize();
@@ -110,7 +110,7 @@ codeunit 134693 "File Scenario Test"
AccountId: Guid;
begin
// [Scenario] When the File scenario is mapped to an existing File account, GetFileAccount returns that account
- PermissionsMock.Set('File Admin');
+ PermissionsMock.Set('File System Admin');
// [Given] An File scenario is mapped to an account
Initialize();
@@ -133,7 +133,7 @@ codeunit 134693 "File Scenario Test"
DefaultAccountId: Guid;
begin
// [Scenario] When the File scenario and the default scenarion are mapped to different File accounts, GetFileAccount returns the corrent account
- PermissionsMock.Set('File Admin');
+ PermissionsMock.Set('File System Admin');
// [Given] An File scenario is mapped to an account, the default scenarion is mapped to another account
Initialize();
@@ -162,7 +162,7 @@ codeunit 134693 "File Scenario Test"
DefaultAccountId: Guid;
begin
// [Scenario] When the File scenario is mapped to a non-existing account and the default scenarion is mapped to an existing accounts, GetFileAccount returns the corrent account
- PermissionsMock.Set('File Admin');
+ PermissionsMock.Set('File System Admin');
// [Given] An File scenario is mapped to a non-exisitng account, the default scenarion is mapped to an existing account
Initialize();
@@ -191,7 +191,7 @@ codeunit 134693 "File Scenario Test"
DefaultAccountId: Guid;
begin
// [Scenario] When the File scenario is mapped to an existing account and the default scenarion is mapped to a non-existing accounts, GetFileAccount returns the corrent account
- PermissionsMock.Set('File Admin');
+ PermissionsMock.Set('File System Admin');
// [Given] An File scenario is mapped to an exisitng account, the default scenarion is mapped to a non-existing account
Initialize();
@@ -220,7 +220,7 @@ codeunit 134693 "File Scenario Test"
Scenario: Enum "File Scenario";
begin
// [Scenario] When SetAccount is called, the entry in the database is as expected
- PermissionsMock.Set('File Admin');
+ PermissionsMock.Set('File System Admin');
// [Given] A random File account
Initialize();
@@ -257,7 +257,7 @@ codeunit 134693 "File Scenario Test"
ResultAccount: Record "File Account";
begin
// [Scenario] When unassigning a scenario then it falls back to the default account.
- PermissionsMock.Set('File Admin');
+ PermissionsMock.Set('File System Admin');
// [Given] Two accounts, one default and one not
Initialize();
diff --git a/src/System Application/Test/File System/src/FileSystemlTest.Codeunit.al b/src/System Application/Test/File System/src/FileSystemlTest.Codeunit.al
deleted file mode 100644
index 3ad8dcdc70..0000000000
--- a/src/System Application/Test/File System/src/FileSystemlTest.Codeunit.al
+++ /dev/null
@@ -1,1552 +0,0 @@
-// ------------------------------------------------------------------------------------------------
-// Copyright (c) Microsoft Corporation. All rights reserved.
-// Licensed under the MIT License. See License.txt in the project root for license information.
-// ------------------------------------------------------------------------------------------------
-
-namespace System.Test.FileSystem;
-
-using System.FileSystem;
-using System.Text;
-using System.TestLibraries.FileSystem;
-using System.Environment;
-using System.TestLibraries.Reflection;
-using System.TestLibraries.Utilities;
-using System.TestLibraries.Security.AccessControl;
-
-codeunit 134685 "File System Test"
-{
- Subtype = Test;
- Permissions = tabledata "Email Message" = rd,
- tabledata "Email Message Attachment" = rd,
- tabledata "Email Recipient" = rd,
- tabledata "Email Outbox" = rimd,
- tabledata "Scheduled Task" = rd,
- tabledata "Sent Email" = rid;
-
- EventSubscriberInstance = Manual;
-
- var
- Assert: Codeunit "Library Assert";
- Email: Codeunit Email;
- Base64Convert: Codeunit "Base64 Convert";
- PermissionsMock: Codeunit "Permissions Mock";
- EmailMessageDoesNotExistMsg: Label 'The email message has been deleted by another user.', Locked = true;
- EmailMessageOpenPermissionErr: Label 'You do not have permission to open the email message.';
- EmailMessageCannotBeEditedErr: Label 'The email message has already been sent and cannot be edited.';
- EmailMessageQueuedCannotDeleteAttachmentErr: Label 'Cannot delete the attachment because the email has been queued to be sent.';
- EmailMessageSentCannotDeleteAttachmentErr: Label 'Cannot delete the attachment because the email has already been sent.';
- AccountNameLbl: Label '%1 (%2)', Locked = true;
- NoRelatedAttachmentsErr: Label 'Did not find any attachments related to this email.';
- OutboxSourceTextLbl: Label '%1: %2', Locked = true;
-
- [Test]
- [Scope('OnPrem')]
- [TransactionModel(TransactionModel::AutoRollback)]
- procedure NonExistingEmailMessageFailsTest()
- var
- Message: Record "Email Message";
- EmailMessage: Codeunit "Email Message";
- begin
- // [Scenario] User cannot save as draft, enqueue, send or open (in editor) a non-existing email message
- PermissionsMock.Set('Email Edit');
-
- // [Given] Create an Email Message and delete the underlying record
- CreateEmail(EmailMessage);
- Assert.IsTrue(Message.Get(EmailMessage.GetId()), 'The record should have been created');
- Message.Delete();
-
- Assert.IsFalse(EmailMessage.Get(EmailMessage.GetId()), 'The email should not exist');
-
- // [When] Saving a non-existing email message as draft
- ClearLastError();
- asserterror Email.SaveAsDraft(EmailMessage);
-
- // [Then] An error occurs
- Assert.ExpectedError(EmailMessageDoesNotExistMsg);
-
- // [When] Enqueuing a non-existing email message
- ClearLastError();
- asserterror Email.Enqueue(EmailMessage);
-
- // [Then] An error occurs
- Assert.ExpectedError(EmailMessageDoesNotExistMsg);
-
- // [When] Sending a non-existing email message
- ClearLastError();
- asserterror Email.Send(EmailMessage);
-
- // [Then] An error occurs
- Assert.ExpectedError(EmailMessageDoesNotExistMsg);
-
- // [When] Opening a non-existing email message
- ClearLastError();
- asserterror Email.OpenInEditor(EmailMessage);
-
- // [Then] An error occurs
- Assert.ExpectedError(EmailMessageDoesNotExistMsg);
-
- // [When] Opening a non-existing email message modally
- ClearLastError();
- asserterror Email.OpenInEditorModally(EmailMessage);
-
- // [Then] An error occurs
- Assert.ExpectedError(EmailMessageDoesNotExistMsg);
- end;
-
- [Test]
- [Scope('OnPrem')]
- [TransactionModel(TransactionModel::AutoRollback)]
- procedure SaveAsDraftEmailMessage()
- var
- EmailOutbox: Record "Email Outbox";
- EmailMessage: Codeunit "Email Message";
- EmptyConnector: Enum "Email Connector";
- EmptyGuid: Guid;
- begin
- // [Scenario] When saving an existing email as draft, it appears in the outbox
- PermissionsMock.Set('Email Edit');
-
- // [Given] An email message
- CreateEmail(EmailMessage);
- Assert.IsTrue(EmailMessage.Get(EmailMessage.GetId()), 'The email message should exist');
-
- // [When] Saving the email message as draft
- ClearLastError();
- Email.SaveAsDraft(EmailMessage);
-
- // [Then] No error occurs
- Assert.AreEqual('', GetLastErrorText(), 'There should be no errors when saving an email.');
-
- // [Then] The draft email should be correct
- EmailOutbox.SetRange("Message Id", EmailMessage.GetId());
- Assert.AreEqual(1, EmailOutbox.Count(), 'There should be only one draft email');
- Assert.IsTrue(EmailOutbox.FindFirst(), 'The message should be in the outbox');
-
- Assert.AreEqual(EmptyGuid, EmailOutbox."Account Id", 'The account should not be set');
- Assert.AreEqual(EmptyConnector, EmailOutbox.Connector, 'The connector should not be set');
- Assert.AreEqual(EmailOutbox.Status::"Draft", EmailOutbox.Status, 'The status should be ''Draft''');
- Assert.AreEqual(UserSecurityId(), EmailOutbox."User Security Id", 'The user security ID should be the current user');
- Assert.AreEqual(EmailMessage.GetSubject(), EmailOutbox.Description, 'The description does not match the email title');
- Assert.AreEqual('', EmailOutbox."Error Message", 'The error message should be blank');
- end;
-
- [Test]
- [Scope('OnPrem')]
- [TransactionModel(TransactionModel::AutoRollback)]
- procedure SaveAsDraftEmailMessageTwice()
- var
- EmailOutbox: Record "Email Outbox";
- EmailMessage: Codeunit "Email Message";
- EmptyConnector: Enum "Email Connector";
- EmptyGuid: Guid;
- begin
- // [Scenario] When enqueuing an existing email, it appears in the outbox
- PermissionsMock.Set('Email Edit');
-
- // [Given] A GUID of an email
- CreateEmail(EmailMessage);
- Assert.IsTrue(EmailMessage.Get(EmailMessage.GetId()), 'The email message should exist');
-
- // [When] Enqueuing the email
- ClearLastError();
- Email.SaveAsDraft(EmailMessage);
-
- // [Then] No error occurs
- Assert.AreEqual('', GetLastErrorText(), 'There should be no errors when saving the email message.');
-
- // [Then] The draft email should be the correct one
- EmailOutbox.SetRange("Message Id", EmailMessage.GetId());
- Assert.AreEqual(1, EmailOutbox.Count(), 'There should be only one enqueued message');
- Assert.IsTrue(EmailOutbox.FindFirst(), 'The message should be queued');
-
- Assert.AreEqual(EmptyGuid, EmailOutbox."Account Id", 'The account should not be set');
- Assert.AreEqual(EmptyConnector, EmailOutbox.Connector, 'The connector should not be set');
- Assert.AreEqual(EmailOutbox.Status::"Draft", EmailOutbox.Status, 'The status should be ''Draft''');
- Assert.AreEqual(UserSecurityId(), EmailOutbox."User Security Id", 'The user security ID should be the current user');
- Assert.AreEqual(EmailMessage.GetSubject(), EmailOutbox.Description, 'The description does not match the email title');
- Assert.AreEqual('', EmailOutbox."Error Message", 'The error message should be blank');
-
- // [When] Saving the email message again
- ClearLastError();
- Email.SaveAsDraft(EmailMessage);
-
- // [Then] No error occurs
- Assert.AreEqual('', GetLastErrorText(), 'There should be no errors when saving the email message again.');
-
- // [Then] The draft email should be the correct one
- EmailOutbox.SetRange("Message Id", EmailMessage.GetId());
- Assert.AreEqual(1, EmailOutbox.Count(), 'There should be only one draft message');
- Assert.IsTrue(EmailOutbox.FindFirst(), 'The message should be queued');
-
- Assert.AreEqual(EmptyGuid, EmailOutbox."Account Id", 'The account should not be set');
- Assert.AreEqual(EmptyConnector, EmailOutbox.Connector, 'The connector should not be set');
- Assert.AreEqual(EmailOutbox.Status::"Draft", EmailOutbox.Status, 'The status should be ''Draft''');
- Assert.AreEqual(UserSecurityId(), EmailOutbox."User Security Id", 'The user security ID should be the current user');
- Assert.AreEqual(EmailMessage.GetSubject(), EmailOutbox.Description, 'The description does not match the email title');
- Assert.AreEqual('', EmailOutbox."Error Message", 'The error message should be blank');
- end;
-
- [Test]
- [HandlerFunctions('CloseEmailEditorHandler')]
- procedure OpenMessageInEditorTest()
- var
- TempAccount: Record "Email Account" temporary;
- EmailMessage: Codeunit "Email Message";
- ConnectorMock: Codeunit "Connector Mock";
- EmailEditor: TestPage "Email Editor";
- Recipients: List of [Text];
- begin
- // Initialize
- ConnectorMock.Initialize();
- ConnectorMock.AddAccount(TempAccount);
-
- PermissionsMock.Set('Email Edit');
-
- Recipients.Add('recipient1@test.com');
- Recipients.Add('recipient2@test.com');
- EmailMessage.Create(Recipients, 'Test subject', 'Test body', true);
- EmailMessage.AddAttachment('Attachment1', 'text/plain', Base64Convert.ToBase64('Content'));
- EmailMessage.AddAttachment('Attachment1', 'text/plain', Base64Convert.ToBase64('Content'));
-
- // Exercise
- EmailEditor.Trap();
- Email.OpenInEditor(EmailMessage);
-
- // Verify
- Assert.AreEqual('', EmailEditor.Account.Value(), 'Account field was not blank.');
- Assert.AreEqual('recipient1@test.com;recipient2@test.com', EmailEditor.ToField.Value(), 'A different To was expected');
- Assert.AreEqual('Test subject', EmailEditor.SubjectField.Value(), 'A different subject was expected.');
- Assert.AreEqual('Test body', EmailEditor.BodyField.Value(), 'A different body was expected.');
- Assert.AreEqual('', EmailEditor.CcField.Value(), 'Cc field was not blank.');
- Assert.AreEqual('', EmailEditor.BccField.Value(), 'Bcc field was not blank.');
-
- Assert.IsTrue(EmailEditor.Attachments.First(), 'First Attachment was not found.');
- Assert.AreEqual('Attachment1', EmailEditor.Attachments.FileName.Value(), 'A different attachment filename was expected');
- Assert.IsTrue(EmailEditor.Attachments.Next(), 'Second Attachment was not found.');
- Assert.AreEqual('Attachment1', EmailEditor.Attachments.FileName.Value(), 'A different attachment filename was expected');
-
- // Exercise
- EmailEditor.Trap();
- Email.OpenInEditor(EmailMessage, TempAccount);
-
- // Verify
- Assert.AreEqual(StrSubstNo(AccountNameLbl, TempAccount.Name, TempAccount."Email Address"), EmailEditor.Account.Value(), 'A different account was expected');
- Assert.AreEqual('recipient1@test.com;recipient2@test.com', EmailEditor.ToField.Value(), 'A different To was expected');
- Assert.AreEqual('Test subject', EmailEditor.SubjectField.Value(), 'A different subject was expected.');
- Assert.AreEqual('Test body', EmailEditor.BodyField.Value(), 'A different body was expected.');
- Assert.AreEqual('', EmailEditor.CcField.Value(), 'Cc field was not blank.');
- Assert.AreEqual('', EmailEditor.BccField.Value(), 'Bcc field was not blank.');
-
- Assert.IsTrue(EmailEditor.Attachments.First(), 'First Attachment was not found.');
- Assert.AreEqual('Attachment1', EmailEditor.Attachments.FileName.Value(), 'A different attachment filename was expected');
- Assert.IsTrue(EmailEditor.Attachments.Next(), 'Second Attachment was not found.');
- Assert.AreEqual('Attachment1', EmailEditor.Attachments.FileName.Value(), 'A different attachment filename was expected');
-
- // Exercise
- EmailEditor.Trap();
- Email.OpenInEditor(EmailMessage, TempAccount);
-
- // Verify
- Assert.AreEqual(StrSubstNo(AccountNameLbl, TempAccount.Name, TempAccount."Email Address"), EmailEditor.Account.Value(), 'A different account was expected');
- Assert.AreEqual('recipient1@test.com;recipient2@test.com', EmailEditor.ToField.Value(), 'A different To was expected');
- Assert.AreEqual('Test subject', EmailEditor.SubjectField.Value(), 'A different subject was expected.');
- Assert.AreEqual('Test body', EmailEditor.BodyField.Value(), 'A different body was expected.');
- Assert.AreEqual('', EmailEditor.CcField.Value(), 'Cc field was not blank.');
- Assert.AreEqual('', EmailEditor.BccField.Value(), 'Bcc field was not blank.');
-
- Assert.IsTrue(EmailEditor.Attachments.First(), 'First Attachment was not found.');
- Assert.AreEqual('Attachment1', EmailEditor.Attachments.FileName.Value(), 'A different attachment filename was expected');
- Assert.IsTrue(EmailEditor.Attachments.Next(), 'Second Attachment was not found.');
- Assert.AreEqual('Attachment1', EmailEditor.Attachments.FileName.Value(), 'A different attachment filename was expected');
- end;
-
- [Test]
- [TransactionModel(TransactionModel::AutoRollback)]
- procedure OpenMessageInEditorForAQueuedMessageTest()
- var
- TempAccount: Record "Email Account" temporary;
- EmailOutBox: Record "Email Outbox";
- EmailMessageAttachment: Record "Email Message Attachment";
- EmailMessage: Codeunit "Email Message";
- ConnectorMock: Codeunit "Connector Mock";
- EmailEditor: TestPage "Email Editor";
- begin
- // Initialize
- ConnectorMock.Initialize();
- ConnectorMock.AddAccount(TempAccount);
-
- PermissionsMock.Set('Email Edit');
-
- CreateEmail(EmailMessage);
- EmailMessage.AddAttachment('Attachment1', 'text/plain', Base64Convert.ToBase64('Content'));
- EmailMessage.AddAttachment('Attachment1', 'text/plain', Base64Convert.ToBase64('Content'));
-
- EmailOutBox.Init();
- EmailOutBox."Account Id" := TempAccount."Account Id";
- EmailOutBox.Connector := Enum::"Email Connector"::"Test Email Connector";
- EmailOutBox."Message Id" := EmailMessage.GetId();
- EmailOutBox.Status := Enum::"Email Status"::Queued;
- EmailOutBox."User Security Id" := UserSecurityId();
- EmailOutBox.Insert();
-
- // Exercise
- EmailEditor.Trap();
- Email.OpenInEditor(EmailMessage);
-
- // Verify
- Assert.IsFalse(EmailEditor.Account.Enabled(), 'Account field was enabled');
- Assert.IsFalse(EmailEditor.ToField.Editable(), 'To field was editable');
- Assert.IsFalse(EmailEditor.CcField.Editable(), 'Cc field was editable');
- Assert.IsFalse(EmailEditor.BccField.Editable(), 'Bcc field was editable');
- Assert.IsFalse(EmailEditor.SubjectField.Editable(), 'Subject field was editable');
- Assert.IsFalse(EmailEditor.BodyField.Editable(), 'Body field was editable');
- Assert.IsFalse(EmailEditor.Attachments.Upload.Visible(), 'Upload Action is visible.');
- Assert.IsFalse(EmailEditor.Send.Enabled(), 'Send Action was not disabled.');
-
- EmailOutBox.Status := Enum::"Email Status"::Processing;
- EmailOutBox.Modify();
-
- // Exercise
- EmailEditor.Trap();
- Email.OpenInEditor(EmailMessage);
-
- // Verify
- Assert.IsFalse(EmailEditor.Account.Enabled(), 'Account field was enabled');
- Assert.IsFalse(EmailEditor.ToField.Editable(), 'To field was editable');
- Assert.IsFalse(EmailEditor.CcField.Editable(), 'Cc field was editable');
- Assert.IsFalse(EmailEditor.BccField.Editable(), 'Bcc field was editable');
- Assert.IsFalse(EmailEditor.SubjectField.Editable(), 'Subject field was editable');
- Assert.IsFalse(EmailEditor.BodyField.Editable(), 'Body field was editable');
- Assert.IsFalse(EmailEditor.Attachments.Upload.Visible(), 'Upload Action is visible.');
- Assert.IsFalse(EmailEditor.Send.Enabled(), 'Send Action was not disabled.');
- EmailMessageAttachment.SetRange("Email Message Id", EmailMessage.GetId());
- EmailMessageAttachment.FindFirst();
- asserterror EmailMessageAttachment.Delete();
- Assert.ExpectedError(EmailMessageQueuedCannotDeleteAttachmentErr);
- end;
-
- [Test]
- [TransactionModel(TransactionModel::AutoRollback)]
- procedure OpenMessageInEditorForAQueuedMessageOwnedByAnotherUserTest()
- var
- TempAccount: Record "Email Account" temporary;
- EmailOutBox: Record "Email Outbox";
- EmailMessage: Codeunit "Email Message";
- ConnectorMock: Codeunit "Connector Mock";
- EmailEditor: TestPage "Email Editor";
- begin
- // Initialize
- ConnectorMock.Initialize();
- ConnectorMock.AddAccount(TempAccount);
-
- PermissionsMock.Set('Email Edit');
-
- CreateEmail(EmailMessage);
-
- EmailOutBox.Init();
- EmailOutBox."Account Id" := TempAccount."Account Id";
- EmailOutBox.Connector := Enum::"Email Connector"::"Test Email Connector";
- EmailOutBox."Message Id" := EmailMessage.GetId();
- EmailOutBox.Status := Enum::"Email Status"::Queued;
- EmailOutbox."User Security Id" := 'd0a983f4-0fc8-4982-8e02-ee9294ab28da'; // Created by another user
- EmailOutBox.Insert();
-
- // Exercise/Verify
- EmailEditor.Trap();
- asserterror Email.OpenInEditor(EmailMessage);
- Assert.ExpectedError(EmailMessageOpenPermissionErr);
- end;
-
- [Test]
- procedure OpenSentMessageInEditorTest()
- var
- TempAccount: Record "Email Account" temporary;
- EmailMessage: Codeunit "Email Message";
- ConnectorMock: Codeunit "Connector Mock";
- EmailEditor: TestPage "Email Editor";
- begin
- // Initialize
- ConnectorMock.Initialize();
- ConnectorMock.AddAccount(TempAccount);
-
- PermissionsMock.Set('Email Edit');
-
- CreateEmail(EmailMessage);
-
- Email.Send(EmailMessage, TempAccount);
-
- // Exercise/Verify
- EmailEditor.Trap();
- asserterror Email.OpenInEditor(EmailMessage);
- Assert.ExpectedError(EmailMessageCannotBeEditedErr);
- end;
-
-
- [Test]
- [HandlerFunctions('EmailEditorHandler,OnEmailEditorClose')]
- procedure OpenInEditorModallyDiscardAOptionTest()
- var
- TempAccount: Record "Email Account" temporary;
- EmailOutbox: Record "Email Outbox";
- SentEmail: Record "Sent Email";
- Message: Record "Email Message";
- Attachment: Record "Email Message Attachment";
- Recipient: Record "Email Recipient";
- EmailMessage: Codeunit "Email Message";
- ConnectorMock: Codeunit "Connector Mock";
- EmailAction: Enum "Email Action";
- begin
- // Initialize
- ConnectorMock.Initialize();
- ConnectorMock.AddAccount(TempAccount);
-
- PermissionsMock.Set('Email Edit');
-
- CreateEmail(EmailMessage);
- EmailMessage.AddAttachment('Attachment1', 'text/plain', Base64Convert.ToBase64('Content'));
-
- OptionChoice := 2; // Discard email
- EmailAction := Email.OpenInEditorModally(EmailMessage, TempAccount);
-
- // Exercise/Verify
- // See EmailEditorHandler
-
- // When the message was discarded, there should be no leftover records
- Assert.AreEqual(Enum::"Email Action"::Discarded, EmailAction, 'Wrong email action returned');
-
- Assert.IsFalse(EmailMessage.Get(EmailMessage.GetId()), 'The email message should not exist');
- Assert.IsFalse(Message.Get(EmailMessage.GetId()), 'The email message record should not exist');
-
- EmailOutbox.SetRange("Message Id", EmailMessage.GetId());
- Assert.IsTrue(EmailOutbox.IsEmpty(), 'There should be no outbox to the discarded message');
-
- SentEmail.SetRange("Message Id", EmailMessage.GetId());
- Assert.IsTrue(SentEmail.IsEmpty(), 'There should be no sent email to the discarded message');
-
- Recipient.SetRange("Email Message Id", EmailMessage.GetId());
- Assert.IsTrue(Recipient.IsEmpty(), 'There should be no recipient to the discarded message');
-
- Attachment.SetRange("Email Message Id", EmailMessage.GetId());
- Assert.IsTrue(Attachment.IsEmpty(), 'There should be no attachments to the discarded message');
- end;
-
- [Test]
- [HandlerFunctions('EmailEditorHandler,OnEmailEditorClose')]
- procedure OpenInEditorModallySaveAsDraftOptionTest()
- var
- TempAccount: Record "Email Account" temporary;
- EmailOutbox: Record "Email Outbox";
- SentEmail: Record "Sent Email";
- Message: Record "Email Message";
- Attachment: Record "Email Message Attachment";
- Recipient: Record "Email Recipient";
- EmailMessage: Codeunit "Email Message";
- ConnectorMock: Codeunit "Connector Mock";
- EmailAction: Enum "Email Action";
- begin
- // Initialize
- ConnectorMock.Initialize();
- ConnectorMock.AddAccount(TempAccount);
-
- PermissionsMock.Set('Email Edit');
-
- CreateEmail(EmailMessage);
- EmailMessage.AddAttachment('Attachment1', 'text/plain', Base64Convert.ToBase64('Content'));
-
- OptionChoice := 1; // Keep as draft
- EmailAction := Email.OpenInEditorModally(EmailMessage, TempAccount);
-
- // Exercise/Verify
- // See EmailEditorHandler
-
- // Exercise
- // When the message was saved as draft (see OnEmailEditorClose)
-
- // Verify
- Assert.AreEqual(Enum::"Email Action"::"Saved As Draft", EmailAction, 'Wrong email action returned');
-
- Assert.IsTrue(EmailMessage.Get(EmailMessage.GetId()), 'The email message should exist');
- Assert.IsTrue(Message.Get(EmailMessage.GetId()), 'The email message record should exist');
-
- EmailOutbox.SetRange("Message Id", EmailMessage.GetId());
- Assert.IsFalse(EmailOutbox.IsEmpty(), 'There should be an outbox to the message');
-
- SentEmail.SetRange("Message Id", EmailMessage.GetId());
- Assert.IsTrue(SentEmail.IsEmpty(), 'There should be no sent email to the message');
-
- Recipient.SetRange("Email Message Id", EmailMessage.GetId());
- Assert.IsFalse(Recipient.IsEmpty(), 'There should be a recipient to the message');
-
- Attachment.SetRange("Email Message Id", EmailMessage.GetId());
- Assert.IsFalse(Attachment.IsEmpty(), 'There should be an attachment to the discarded message');
- end;
-
- [Test]
- [HandlerFunctions('SendEmailEditorHandler')]
- procedure OpenInEditorModallySendActionTest()
- var
- TempAccount: Record "Email Account" temporary;
- EmailOutbox: Record "Email Outbox";
- SentEmail: Record "Sent Email";
- Message: Record "Email Message";
- Attachment: Record "Email Message Attachment";
- Recipient: Record "Email Recipient";
- EmailMessage: Codeunit "Email Message";
- ConnectorMock: Codeunit "Connector Mock";
- EmailAction: Enum "Email Action";
- begin
- // Initialize
- ConnectorMock.Initialize();
- ConnectorMock.AddAccount(TempAccount);
-
- PermissionsMock.Set('Email Edit');
-
- CreateEmail(EmailMessage);
- EmailMessage.AddAttachment('Attachment1', 'text/plain', Base64Convert.ToBase64('Content'));
-
- EmailAction := Email.OpenInEditorModally(EmailMessage, TempAccount);
-
- // Exercise
- // See SendEmailEditorHandlers
-
- // Verify
- Assert.AreEqual(Enum::"Email Action"::Sent, EmailAction, 'Wrong email action returned');
-
- Assert.IsTrue(EmailMessage.Get(EmailMessage.GetId()), 'The email message should exist');
- Assert.IsTrue(Message.Get(EmailMessage.GetId()), 'The email message record should exist');
-
- EmailOutbox.SetRange("Message Id", EmailMessage.GetId());
- Assert.IsTrue(EmailOutbox.IsEmpty(), 'There should be no outbox to the message');
-
- SentEmail.SetRange("Message Id", EmailMessage.GetId());
- Assert.IsFalse(SentEmail.IsEmpty(), 'There should be a sent email to the message');
-
- Recipient.SetRange("Email Message Id", EmailMessage.GetId());
- Assert.IsFalse(Recipient.IsEmpty(), 'There should be a recipient to the message');
-
- Attachment.SetRange("Email Message Id", EmailMessage.GetId());
- Assert.IsFalse(Attachment.IsEmpty(), 'There should be an attachment to the discarded message');
- end;
-
- [Test]
- [HandlerFunctions('DiscardEmailEditorHandler,ConfirmYes')]
- procedure OpenInEditorModallyDiscardActionTest()
- var
- TempAccount: Record "Email Account" temporary;
- EmailOutbox: Record "Email Outbox";
- SentEmail: Record "Sent Email";
- Message: Record "Email Message";
- Attachment: Record "Email Message Attachment";
- Recipient: Record "Email Recipient";
- EmailMessage: Codeunit "Email Message";
- ConnectorMock: Codeunit "Connector Mock";
- EmailAction: Enum "Email Action";
- begin
- // Initialize
- ConnectorMock.Initialize();
- ConnectorMock.AddAccount(TempAccount);
-
- PermissionsMock.Set('Email Edit');
-
- CreateEmail(EmailMessage);
- EmailMessage.AddAttachment('Attachment1', 'text/plain', Base64Convert.ToBase64('Content'));
-
- EmailAction := Email.OpenInEditorModally(EmailMessage, TempAccount);
-
- // Exercise
- // See DiscardEmailEditorHandler
-
- // Verify
- Assert.AreEqual(Enum::"Email Action"::Discarded, EmailAction, 'Wrong email action returned');
-
- Assert.IsFalse(EmailMessage.Get(EmailMessage.GetId()), 'The email message should not exist');
- Assert.IsFalse(Message.Get(EmailMessage.GetId()), 'The email message record should not exist');
-
- EmailOutbox.SetRange("Message Id", EmailMessage.GetId());
- Assert.IsTrue(EmailOutbox.IsEmpty(), 'There should be no outbox to the message');
-
- SentEmail.SetRange("Message Id", EmailMessage.GetId());
- Assert.IsTrue(SentEmail.IsEmpty(), 'There should be no sent email to the message');
-
- Recipient.SetRange("Email Message Id", EmailMessage.GetId());
- Assert.IsTrue(Recipient.IsEmpty(), 'There should be no recipient to the message');
-
- Attachment.SetRange("Email Message Id", EmailMessage.GetId());
- Assert.IsTrue(Attachment.IsEmpty(), 'There should be no attachment to the discarded message');
- end;
-
- [Test]
- [Scope('OnPrem')]
- [TransactionModel(TransactionModel::AutoRollback)]
- procedure EnqueueExistingEmailTest()
- var
- EmailOutbox: Record "Email Outbox";
- EmailMessage: Codeunit "Email Message";
- ConnectorMock: Codeunit "Connector Mock";
- AccountId: Guid;
- begin
- // [Scenario] When enqueuing an existing email, it appears in the outbox
- PermissionsMock.Set('Email Edit');
-
- // [Given] An email message and an email account
- CreateEmail(EmailMessage);
- Assert.IsTrue(EmailMessage.Get(EmailMessage.GetId()), 'The email should exist');
- ConnectorMock.Initialize();
- ConnectorMock.AddAccount(AccountId);
-
- // [When] Enqueuing the email message with the email account
- ClearLastError();
- Email.Enqueue(EmailMessage, AccountId, Enum::"Email Connector"::"Test Email Connector");
-
- // [Then] No error occurs
- Assert.AreEqual('', GetLastErrorText(), 'There should be no errors when enqueuing an email.');
-
- // [Then] The enqueued email should be the correct one
- EmailOutbox.SetRange("Message Id", EmailMessage.GetId());
- Assert.AreEqual(1, EmailOutbox.Count(), 'There should be only one enqueued message');
- Assert.IsTrue(EmailOutbox.FindFirst(), 'The message should be queued');
-
- Assert.AreEqual(AccountId, EmailOutbox."Account Id", 'The account should be set');
- Assert.AreEqual(Enum::"Email Connector"::"Test Email Connector", EmailOutbox.Connector, 'The connector should be set');
- Assert.AreEqual(EmailOutbox.Status::Queued, EmailOutbox.Status, 'The status should be ''Queued''');
- Assert.AreEqual(UserSecurityId(), EmailOutbox."User Security Id", 'The user security ID should be the current user');
- Assert.AreEqual(EmailMessage.GetSubject(), EmailOutbox.Description, 'The description does not match the email title');
- Assert.AreEqual('', EmailOutbox."Error Message", 'The error message should be blank');
- end;
-
- [Test]
- [Scope('OnPrem')]
- [TransactionModel(TransactionModel::AutoRollback)]
- procedure EnqueueScheduledEmailTest()
- var
- EmailOutbox: Record "Email Outbox";
- ScheduleTasks: Record "Scheduled Task";
- EmailMessage: Codeunit "Email Message";
- ConnectorMock: Codeunit "Connector Mock";
- AccountId: Guid;
- DateTime: DateTime;
- MaxDurationDifference: Duration;
- begin
- // [Scenario] When enqueuing an existing email, it appears in the outbox
- PermissionsMock.Set('Email Edit');
-
- // [Given] An email message and an email account
- CreateEmail(EmailMessage);
- Assert.IsTrue(EmailMessage.Get(EmailMessage.GetId()), 'The email should exist');
- ConnectorMock.Initialize();
- ConnectorMock.AddAccount(AccountId);
-
- // [When] Enqueuing the email message with the email account
- ScheduleTasks.DeleteAll();
- ClearLastError();
-
- DateTime := CreateDateTime(CalcDate('<+1D>', Today()), Time());
- Email.Enqueue(EmailMessage, AccountId, Enum::"Email Connector"::"Test Email Connector", DateTime);
-
- // [Then] No error occurs
- Assert.AreEqual('', GetLastErrorText(), 'There should be no errors when enqueuing an email.');
-
- // [Then] Job is enqueued
- Assert.AreEqual(ScheduleTasks.Count, 1, 'Enqueue should only add one entry to scheduled tasks');
- Assert.IsTrue(ScheduleTasks.FindFirst(), 'The job should be in scheduled tasks');
- MaxDurationDifference := 100; // 100 ms
- Assert.AreEqualDateTime(ScheduleTasks."Not Before", DateTime, MaxDurationDifference, 'The jobs not before date should be equal to the datetime provided when enqueueing');
-
- // [Then] The enqueued email should be the correct one
- EmailOutbox.SetRange("Message Id", EmailMessage.GetId());
- Assert.AreEqual(1, EmailOutbox.Count(), 'There should be only one enqueued message');
- Assert.IsTrue(EmailOutbox.FindFirst(), 'The message should be queued');
-
- Assert.AreEqual(AccountId, EmailOutbox."Account Id", 'The account should be set');
- Assert.AreEqual(Enum::"Email Connector"::"Test Email Connector", EmailOutbox.Connector, 'The connector should be set');
- Assert.AreEqual(EmailOutbox.Status::Queued, EmailOutbox.Status, 'The status should be ''Queued''');
- Assert.AreEqual(UserSecurityId(), EmailOutbox."User Security Id", 'The user security ID should be the current user');
- Assert.AreEqual(EmailMessage.GetSubject(), EmailOutbox.Description, 'The description does not match the email title');
- Assert.AreEqual('', EmailOutbox."Error Message", 'The error message should be blank');
- Assert.AreEqual(DateTime, EmailOutbox."Date Sending", 'The date sending does not match the datetime provided when enqueueing');
- end;
-
- [Test]
- [Scope('OnPrem')]
- procedure SendEmailMessageFailTest()
- var
- EmailOutbox: Record "Email Outbox";
- EmailMessage: Codeunit "Email Message";
- ConnectorMock: Codeunit "Connector Mock";
- Connector: Enum "Email Connector";
- EmailStatus: Enum "Email Status";
- AccountId: Guid;
- begin
- // [Scenario] When sending an email on the foreground and the process fails, an error is shown
- PermissionsMock.Set('Email Edit');
-
- // [Given] An email message and an email account
- CreateEmail(EmailMessage);
- Assert.IsTrue(EmailMessage.Get(EmailMessage.GetId()), 'The email should exist');
- ConnectorMock.Initialize();
- ConnectorMock.AddAccount(AccountId);
-
- // [When] Sending the email fails
- ConnectorMock.FailOnSend(true);
- Assert.IsFalse(Email.Send(EmailMessage, AccountId, Connector::"Test Email Connector"), 'Sending an email should have failed');
-
- // [Then] The error is as expected
- EmailOutbox.SetRange("Account Id", AccountId);
- EmailOutbox.SetRange("Message Id", EmailMessage.GetId());
-
- Assert.IsTrue(EmailOutbox.FindFirst(), 'The email outbox entry should exist');
- Assert.AreEqual(Connector::"Test Email Connector".AsInteger(), EmailOutbox.Connector.AsInteger(), 'Wrong connector');
- Assert.AreEqual(EmailStatus::Failed.AsInteger(), EmailOutbox.Status.AsInteger(), 'Wrong status');
- Assert.AreEqual('Failed to send email', EmailOutbox."Error Message", 'Wrong error message');
- end;
-
- [Test]
- [Scope('OnPrem')]
- procedure SendEmailMessageSuccessTest()
- var
- EmailOutbox: Record "Email Outbox";
- EmailMessageAttachment: Record "Email Message Attachment";
- SentEmail: Record "Sent Email";
- EmailAccount: Record "Email Account";
- EmailMessage: Codeunit "Email Message";
- ConnectorMock: Codeunit "Connector Mock";
- Connector: Enum "Email Connector";
- begin
- // [Scenario] When successfuly sending an email, a recond is added on the Sent Emails table
- PermissionsMock.Set('Email Edit');
-
- // [Given] An email message and an email account
- CreateEmail(EmailMessage);
- EmailMessage.AddAttachment('Attachment1', 'text/plain', Base64Convert.ToBase64('Content'));
-
- Assert.IsTrue(EmailMessage.Get(EmailMessage.GetId()), 'The email should exist');
-
- ConnectorMock.Initialize();
- ConnectorMock.AddAccount(EmailAccount);
-
- // [When] The email is Sent
- Assert.IsTrue(Email.Send(EmailMessage, EmailAccount), 'Sending an email should have succeeded');
-
- // [Then] There is a Sent Mail recond and no Outbox record
- SentEmail.SetRange("Account Id", EmailAccount."Account Id");
- SentEmail.SetRange("Message Id", EmailMessage.GetId());
-
- Assert.IsTrue(SentEmail.FindFirst(), 'The email sent record should exist');
- Assert.AreEqual(EmailMessage.GetId(), SentEmail."Message Id", 'Wrong email message');
- Assert.AreEqual(EmailAccount."Email Address", SentEmail."Sent From", 'Wrong email address (sent from)');
- Assert.AreNotEqual(0DT, SentEmail."Date Time Sent", 'The Date Time Sent should be filled');
- Assert.AreEqual(EmailAccount."Account Id", SentEmail."Account Id", 'Wrong account');
- Assert.AreEqual(Connector::"Test Email Connector".AsInteger(), SentEmail.Connector.AsInteger(), 'Wrong connector');
- Assert.AreEqual(EmailMessage.GetSubject(), SentEmail.Description, 'Wrong description');
-
- // There is no related outbox
- EmailOutbox.SetRange("Account Id", EmailAccount."Account Id");
- EmailOutbox.SetRange("Message Id", EmailMessage.GetId());
-
- Assert.AreEqual(0, EmailOutbox.Count(), 'Email Outbox was not empty.');
-
- //[Then] The attachments cannot be deleted
- EmailMessageAttachment.SetRange("Email Message Id", EmailMessage.GetId());
- EmailMessageAttachment.FindFirst();
-
- asserterror EmailMessageAttachment.Delete();
- Assert.ExpectedError(EmailMessageSentCannotDeleteAttachmentErr);
- end;
-
- [Test]
- [Scope('OnPrem')]
- procedure ShowSourceRecordInOutbox()
- var
- EmailOutbox: Record "Email Outbox";
- EmailMessage: Codeunit "Email Message";
- Any: Codeunit Any;
- EmailTest: Codeunit "Email Test";
- EmailOutboxPage: Page "Email Outbox";
- EmailOutboxTestPage: TestPage "Email Outbox";
- TableId: Integer;
- SystemId: Guid;
- begin
- BindSubscription(EmailTest);
-
- PermissionsMock.Set('Email Edit');
-
- // [Scenario] Emails with source document, will see the Source Document button
- // [Given] An Email with table id and source system id
- TableId := Any.IntegerInRange(1, 10000);
- SystemId := Any.GuidValue();
-
- // [When] The email is created and saved as draft
- CreateEmailWithSource(EmailMessage, TableId, SystemId);
-
- // [When] The email is created and saved as draft
- Email.SaveAsDraft(EmailMessage, EmailOutbox);
-
- // [And] The Show Source Document button is visible
- EmailOutboxTestPage.Trap();
- EmailOutboxPage.SetRecord(EmailOutbox);
- EmailOutboxPage.Run();
-
- Assert.IsTrue(EmailOutboxTestPage.ShowSourceRecord.Visible(), 'Show Source Record action should be visible');
-
- // [When] Show Source Document button is clicked
- ClearLastError();
- EmailOutboxTestPage.ShowSourceRecord.Invoke();
-
- // [Then] No error appears
- Assert.AreEqual('', GetLastErrorText, 'An error occured');
- end;
-
- [Test]
- [Scope('OnPrem')]
- [HandlerFunctions('RelationPickerHandler')]
- procedure ShowMultipleSourceRecords()
- var
- EmailOutbox: Record "Email Outbox";
- EmailMessageRecord: Record "Email Message";
- EmailMessage: Codeunit "Email Message";
- EmailTest: Codeunit "Email Test";
- EmailOutboxPage: Page "Email Outbox";
- EmailOutboxTestPage: TestPage "Email Outbox";
- TableId: Integer;
- SystemId: Guid;
- begin
- BindSubscription(EmailTest);
- EmailOutbox.DeleteAll();
-
- // [Scenario] Emails with multiple source documents, will see the email relation picker
- // [Given] An Email with table id and source system id
-
- // [And] The email is with a source and saved as draft
- CreateEmail(EmailMessage);
- Email.SaveAsDraft(EmailMessage, EmailOutbox);
-
- // [When] An extra relation is added - We use email outbox to have a record that actually exists
- EmailMessageRecord.Get(EmailMessage.GetId());
- TableId := Database::"Email Outbox";
- SystemId := EmailOutbox.SystemId;
- Email.AddRelation(EmailMessage, TableId, SystemId, Enum::"Email Relation Type"::"Primary Source", Enum::"Email Relation Origin"::"Compose Context");
- Email.AddRelation(EmailMessage, Database::"Email Message", EmailMessageRecord.SystemId, Enum::"Email Relation Type"::"Related Entity", Enum::"Email Relation Origin"::"Compose Context");
-
- // [And] The Show Source Document button is clicked
- EmailOutboxTestPage.Trap();
- EmailOutboxPage.SetRecord(EmailOutbox);
- EmailOutboxPage.Run();
-
- Assert.IsTrue(EmailOutboxTestPage.ShowSourceRecord.Visible(), 'Show Source Record action should be visible');
- Assert.IsTrue(EmailOutboxTestPage.ShowSourceRecord.Enabled(), 'Show Source Record action should be enabled');
- EmailOutboxTestPage.ShowSourceRecord.Invoke();
-
- // [Then] Email picker modal appears
- end;
-
- [Test]
- [Scope('OnPrem')]
- procedure EmailWithoutSourceInOutbox()
- var
- EmailOutbox: Record "Email Outbox";
- EmailMessage: Codeunit "Email Message";
- EmailTest: Codeunit "Email Test";
- EmailOutboxPage: Page "Email Outbox";
- EmailOutboxTestPage: TestPage "Email Outbox";
- begin
- BindSubscription(EmailTest);
-
- PermissionsMock.Set('Email Edit');
- EmailOutbox.DeleteAll();
-
- // [Scenario] Emails with source document, will see the Source Document button
- // [Given] An Email with table id and source system id
-
- // [When] The email is created and saved as draft
- CreateEmail(EmailMessage);
- Email.SaveAsDraft(EmailMessage, EmailOutbox);
-
- // [When] The Email Outbox page is opened.
- EmailOutboxTestPage.Trap();
- EmailOutboxPage.SetRecord(EmailOutbox);
- EmailOutboxPage.Run();
-
- // [Then] The Show Source action is visible and disabled.
- Assert.IsTrue(EmailOutboxTestPage.ShowSourceRecord.Visible(), 'Show Source Record action should be visible');
- Assert.IsFalse(EmailOutboxTestPage.ShowSourceRecord.Enabled(), 'Show Source Record action should be disabled');
- end;
-
-
- [Test]
- [Scope('OnPrem')]
- procedure EmailWithSourceNoSubscriber()
- var
- EmailOutbox: Record "Email Outbox";
- EmailMessage: Codeunit "Email Message";
- Any: Codeunit Any;
- EmailOutboxPage: Page "Email Outbox";
- EmailOutboxTestPage: TestPage "Email Outbox";
- TableId: Integer;
- SystemId: Guid;
- begin
- // [Scenario] Emails with source document, will see the Source Document button
- PermissionsMock.Set('Email Edit');
-
- // [Given] An Email with table id and source system id
- TableId := Any.IntegerInRange(1, 10000);
- SystemId := Any.GuidValue();
-
- // [When] The email is created and saved as draft
- CreateEmailWithSource(EmailMessage, TableId, SystemId);
-
- // [When] The email is created and saved as draft
- CreateEmail(EmailMessage);
- Email.SaveAsDraft(EmailMessage, EmailOutbox);
-
- // [When] The Email Outbox page is opened.
- EmailOutboxTestPage.Trap();
- EmailOutboxPage.SetRecord(EmailOutbox);
- EmailOutboxPage.Run();
-
- // [Then] The Show Source action is visible and disabled.
- Assert.IsTrue(EmailOutboxTestPage.ShowSourceRecord.Visible(), 'Show Source Record action should be visible');
- Assert.IsFalse(EmailOutboxTestPage.ShowSourceRecord.Enabled(), 'Show Source Record action should be disabled');
- end;
-
- [Test]
- [Scope('OnPrem')]
- procedure SendEmailMessageWithSourceTest()
- var
- TempSentEmail: Record "Sent Email" temporary;
- EmailAccount: Record "Email Account";
- EmailMessage: Codeunit "Email Message";
- ConnectorMock: Codeunit "Connector Mock";
- Any: Codeunit Any;
- SystemId: Guid;
- TableId, NumberOfEmails, i : Integer;
- MessageIds: List of [Guid];
- begin
- // [Scenario] When successfuly sending an email with source, a record is added to the email source document table and sent emails table.
- PermissionsMock.Set('Email Edit');
-
- // [Given] An email with source and an email account
- TableId := Any.IntegerInRange(1, 10000);
- SystemId := Any.GuidValue();
-
- ConnectorMock.Initialize();
- ConnectorMock.AddAccount(EmailAccount);
-
- NumberOfEmails := Any.IntegerInRange(2, 5);
-
- for i := 1 to NumberOfEmails do begin
- CreateEmailWithSource(EmailMessage, TableId, SystemId);
- Assert.IsTrue(EmailMessage.Get(EmailMessage.GetId()), 'The email should exist');
- MessageIds.Add(EmailMessage.GetId());
-
- // [When] The email is Sent
- Assert.IsTrue(Email.Send(EmailMessage, EmailAccount), 'Sending an email should have succeeded');
- end;
-
- Email.GetSentEmailsForRecord(TableId, SystemId, TempSentEmail);
-
- for i := 1 to NumberOfEmails do begin
- TempSentEmail.SetCurrentKey("Message Id");
- TempSentEmail.SetRange("Message Id", MessageIds.Get(i));
- Assert.AreEqual(1, TempSentEmail.Count(), 'Did not find the email in Sent Emails ');
- end;
- end;
-
- [Test]
- [Scope('OnPrem')]
- [HandlerFunctions('RelatedAttachmentsHandler,CloseEmailEditorHandler')]
- procedure AttachFromRelatedRecords()
- var
- EmailMessageAttachments: Record "Email Message Attachment";
- EmailOutbox: Record "Email Outbox";
- EmailMessage: Codeunit "Email Message";
- EmailTest: Codeunit "Email Test";
- EmailEditorPage: TestPage "Email Editor";
- TableId: Integer;
- SystemId: Guid;
- SourceText: Text;
- begin
- BindSubscription(EmailTest);
- VariableStorage.Clear();
-
- // [Given] A created email
- CreateEmail(EmailMessage);
- Email.SaveAsDraft(EmailMessage, EmailOutbox);
-
- // [And] A related record to the email (in this case, the email is related to an email in the outbox)
- TableId := Database::"Email Outbox";
- SystemId := EmailOutbox.SystemId;
-
- Email.AddRelation(EmailMessage, TableId, SystemId, Enum::"Email Relation Type"::"Primary Source", Enum::"Email Relation Origin"::"Compose Context");
-
- SourceText := StrSubstNo(OutboxSourceTextLbl, EmailOutbox.TableCaption(), Format(EmailOutbox.Id));
- VariableStorage.Enqueue(SourceText);
-
- // [When] Opening the Email Related Attachments page
- EmailEditorPage.Trap();
- Email.OpenInEditor(EmailMessage);
- EmailEditorPage.Attachments.SourceAttachments.Invoke();
-
- // [Then] Attachments added through the 'OnFindRelatedAttachments' event are displayed
- // [And] A related attachment is added
-
- // [Then] The related attachment is added as an attachment to the email
- EmailMessageAttachments.SetRange("Email Message Id", EmailMessage.GetId());
- EmailMessageAttachments.FindSet();
- Assert.AreEqual(1, EmailMessageAttachments.Count(), 'Related attachment wasnt attached to the email.');
- Assert.AreEqual('Attachment1', EmailMessageAttachments."Attachment Name", 'Wrong attachment was attached to email.');
- AssertVariableStorageEmpty();
- end;
-
- [Test]
- [Scope('OnPrem')]
- procedure GetRelatedAttachmentsTest()
- var
- EmailRelatedAttachment: Record "Email Related Attachment";
- EmailOutbox: Record "Email Outbox";
- EmailMessage: Codeunit "Email Message";
- EmailTest: Codeunit "Email Test";
- EmailEditor: Codeunit "Email Editor";
- TableId: Integer;
- SystemId: Guid;
- SourceText: Text;
- begin
- BindSubscription(EmailTest);
- VariableStorage.Clear();
-
- // [Given] A created email
- CreateEmail(EmailMessage);
- Email.SaveAsDraft(EmailMessage, EmailOutbox);
-
- // [And] A related record to the email (in this case, the email is related to an email in the outbox)
- TableId := Database::"Email Outbox";
- SystemId := EmailOutbox.SystemId;
-
- Email.AddRelation(EmailMessage, TableId, SystemId, Enum::"Email Relation Type"::"Primary Source", Enum::"Email Relation Origin"::"Compose Context");
-
- SourceText := StrSubstNo(OutboxSourceTextLbl, EmailOutbox.TableCaption(), Format(EmailOutbox.Id));
- VariableStorage.Enqueue(SourceText);
-
- EmailEditor.GetRelatedAttachments(EmailMessage.GetId(), EmailRelatedAttachment);
-
- Assert.AreEqual(1, EmailRelatedAttachment.Count(), 'Wrong number of attachments.');
- Assert.AreEqual('Attachment1', EmailRelatedAttachment."Attachment Name", 'Wrong attachmentname');
- end;
-
- [Test]
- [Scope('OnPrem')]
- [HandlerFunctions('RelatedAttachmentsHandler,CloseEmailEditorHandler')]
- procedure FailedAttachFromRelatedRecords()
- var
- EmailMessage: Codeunit "Email Message";
- EmailTest: Codeunit "Email Test";
- EmailEditorPage: TestPage "Email Editor";
- begin
- BindSubscription(EmailTest);
-
- // [Given] A created email without source record
- CreateEmail(EmailMessage);
-
- // [When] Opening the Email Related Attachments page and getting related attachments
- EmailEditorPage.Trap();
- Email.OpenInEditor(EmailMessage);
- asserterror EmailEditorPage.Attachments.SourceAttachments.Invoke();
-
- // [Then] An error message is displayed
- Assert.ExpectedError(NoRelatedAttachmentsErr);
- end;
-
- [Test]
- [Scope('OnPrem')]
- procedure SendEmailInBackgroundSuccessTest()
- var
- EmailAccount: Record "Email Account";
- EmailMessage: Codeunit "Email Message";
- ConnectorMock: Codeunit "Connector Mock";
- TestClientType: Codeunit "Test Client Type Subscriber";
- EmailTest: Codeunit "Email Test";
- Variable: Variant;
- Status: Boolean;
- MessageID: Guid;
- begin
- // [Scenario] When Sending the email in the background an event is fired to nothify for the status of the email
- PermissionsMock.Set('Email Edit');
-
- TestClientType.SetClientType(ClientType::Background);
- BindSubscription(TestClientType);
- BindSubscription(EmailTest);
-
- // [Given] An email message and an email account
- CreateEmail(EmailMessage);
- Assert.IsTrue(EmailMessage.Get(EmailMessage.GetId()), 'The email should exist');
-
- ConnectorMock.Initialize();
- ConnectorMock.AddAccount(EmailAccount);
-
- // [When] The email is Sent
- Email.Send(EmailMessage, EmailAccount);
-
- // [Then] An event is fired to notify for the status of the email
- EmailTest.DequeueVariable(Variable);
- MessageID := Variable;
- EmailTest.DequeueVariable(Variable);
- Status := Variable;
-
- // [Then] The event was fired once
- EmailTest.AssertVariableStorageEmpty();
- Assert.AreEqual(MessageID, EmailMessage.GetId(), 'A different Email was expected');
- Assert.IsTrue(Status, 'The email should have been sent');
-
- UnBindSubscription(EmailTest);
- UnBindSubscription(TestClientType);
- end;
-
- [Test]
- [Scope('OnPrem')]
- procedure SendEmailInBackgroundFailTest()
- var
- EmailAccount: Record "Email Account";
- EmailMessage: Codeunit "Email Message";
- ConnectorMock: Codeunit "Connector Mock";
- TestClientType: Codeunit "Test Client Type Subscriber";
- EmailTest: Codeunit "Email Test";
- Variable: Variant;
- Status: Boolean;
- MessageID: Guid;
- begin
- // [Scenario] When Sending the email in the background an event is fired to nothify for the status of the email
- PermissionsMock.Set('Email Edit');
-
- TestClientType.SetClientType(ClientType::Background);
- BindSubscription(TestClientType);
- BindSubscription(EmailTest);
-
- // [Given] An email message and an email account
- CreateEmail(EmailMessage);
- Assert.IsTrue(EmailMessage.Get(EmailMessage.GetId()), 'The email should exist');
-
- ConnectorMock.Initialize();
- ConnectorMock.AddAccount(EmailAccount);
- ConnectorMock.FailOnSend(true);
-
- // [When] The email is Sent
- Email.Send(EmailMessage, EmailAccount);
-
- // [Then] An event is fired to notify for the status of the email
- EmailTest.DequeueVariable(Variable);
- MessageID := Variable;
- EmailTest.DequeueVariable(Variable);
- Status := Variable;
-
- // [Then] The event was fired once
- EmailTest.AssertVariableStorageEmpty();
- Assert.AreEqual(MessageID, EmailMessage.GetId(), 'A different Email was expected');
- Assert.IsFalse(Status, 'The email should not have been sent');
-
- UnBindSubscription(EmailTest);
- UnBindSubscription(TestClientType);
- end;
-
- [Test]
- [Scope('OnPrem')]
- procedure SendEmailInBackgroundFailSubscriberFailsTest()
- var
- EmailAccount: Record "Email Account";
- EmailMessage: Codeunit "Email Message";
- ConnectorMock: Codeunit "Connector Mock";
- TestClientType: Codeunit "Test Client Type Subscriber";
- EmailTest: Codeunit "Email Test";
- Variable: Variant;
- Status: Boolean;
- MessageID: Guid;
- begin
- // [Scenario] When an error occurs on the subscriber it does not propagate up the stack and the notification is sent only once
- PermissionsMock.Set('Email Edit');
-
- TestClientType.SetClientType(ClientType::Background);
- BindSubscription(TestClientType);
- BindSubscription(EmailTest);
- EmailTest.ThrowErrorOnAfterSendEmail();
-
- // [Given] An email message and an email account
- CreateEmail(EmailMessage);
-
- Assert.IsTrue(EmailMessage.Get(EmailMessage.GetId()), 'The email should exist');
-
- ConnectorMock.Initialize();
- ConnectorMock.AddAccount(EmailAccount);
- ConnectorMock.FailOnSend(true);
-
- // [When] The email is Sent
- Email.Send(EmailMessage, EmailAccount);
-
- // [Then] An event is fired to notify for the status of the email
- EmailTest.DequeueVariable(Variable);
- MessageID := Variable;
- EmailTest.DequeueVariable(Variable);
- Status := Variable;
-
- // [Then] The event was fired once
- EmailTest.AssertVariableStorageEmpty();
- Assert.AreEqual(MessageID, EmailMessage.GetId(), 'A different Email was expected');
- Assert.IsFalse(Status, 'The email should not have been sent');
-
- UnBindSubscription(EmailTest);
- UnBindSubscription(TestClientType);
- end;
-
-
- [Test]
- [Scope('OnPrem')]
- procedure SendEmailInBackgroundSuccessSubscriberFailsTest()
- var
- EmailAccount: Record "Email Account";
- EmailOutbox: Record "Email Outbox";
- EmailMessage: Codeunit "Email Message";
- ConnectorMock: Codeunit "Connector Mock";
- TestClientType: Codeunit "Test Client Type Subscriber";
- EmailTest: Codeunit "Email Test";
- Variable: Variant;
- Status: Boolean;
- MessageID: Guid;
- begin
- // [Scenario] When an error occurs on the subscriber it does not propagate up the stack and the notification is sent only once
- PermissionsMock.Set('Email Edit');
-
- TestClientType.SetClientType(ClientType::Background);
- BindSubscription(TestClientType);
- BindSubscription(EmailTest);
- EmailTest.ThrowErrorOnAfterSendEmail();
-
- // [Given] An email message and an email account
- CreateEmail(EmailMessage);
-
- Assert.IsTrue(EmailMessage.Get(EmailMessage.GetId()), 'The email should exist');
-
- ConnectorMock.Initialize();
- ConnectorMock.AddAccount(EmailAccount);
-
- // [When] The email is Sent
- Email.Send(EmailMessage, EmailAccount);
-
- // [Then] An event is fired to notify for the status of the email
- EmailTest.DequeueVariable(Variable);
- MessageID := Variable;
- EmailTest.DequeueVariable(Variable);
- Status := Variable;
- // [Then] The event was fired once
- EmailTest.AssertVariableStorageEmpty();
- Assert.AreEqual(MessageID, EmailMessage.GetId(), 'A different Email was expected');
- Assert.IsTrue(Status, 'The email should have been sent');
-
- EmailOutbox.SetRange("Message Id", EmailMessage.GetId());
- Assert.IsTrue(EmailOutbox.IsEmpty(), 'Email outbox should have been deleted.');
-
- UnBindSubscription(EmailTest);
- UnBindSubscription(TestClientType);
- end;
-
- [Test]
- procedure ResendSentEmailFromAnotherUserTest()
- var
- SentEmail: Record "Sent Email";
- Any: Codeunit Any;
- EmailViewer: Codeunit "Email Viewer";
- begin
- // Create a sent email
- PermissionsMock.Set('Email Edit');
-
- SentEmail.Init();
- SentEmail.Description := CopyStr(Any.UnicodeText(50), 1, MaxStrLen(SentEmail.Description));
- SentEmail."Date Time Sent" := CurrentDateTime();
- SentEmail."User Security Id" := CreateGuid(); // Created by another user
- SentEmail.Insert();
-
- asserterror EmailViewer.Resend(SentEmail);
- Assert.ExpectedError(EmailMessageOpenPermissionErr);
-
- asserterror EmailViewer.EditAndSend(SentEmail);
- Assert.ExpectedError(EmailMessageOpenPermissionErr);
- end;
-
- [Test]
- procedure GetSourceRecordInOutbox()
- var
- SourceEmailOutbox, EmailOutbox : Record "Email Outbox";
- TempEmailOutbox: Record "Email Outbox" temporary;
- EmailMessage: Codeunit "Email Message";
- Any: Codeunit Any;
- EmailTest: Codeunit "Email Test";
- MessageIds: List of [Guid];
- SystemId: Guid;
- TableId: Integer;
- NumberOfEmails, i : Integer;
- begin
- BindSubscription(EmailTest);
-
- PermissionsMock.Set('Email Edit');
- EmailOutbox.DeleteAll();
-
- // [Scenario] Emails with source document, GetEmailOutboxForRecord procedure will return Outbox Emails
- // [Given] Source Record - Email Outbox used as a source record for test email
- CreateEmail(EmailMessage);
- Email.SaveAsDraft(EmailMessage, SourceEmailOutbox);
- TableId := Database::"Email Outbox";
- SystemId := SourceEmailOutbox.SystemId;
-
- // [When] Several emails are created and saved as draft
- NumberOfEmails := Any.IntegerInRange(2, 5);
-
- for i := 1 to NumberOfEmails do begin
- Clear(EmailOutbox);
- CreateEmailWithSource(EmailMessage, TableId, SystemId);
- Email.SaveAsDraft(EmailMessage, EmailOutbox);
- MessageIds.Add(EmailMessage.GetId());
- end;
-
- // [Then] GetEmailOutboxForRecord procedure return related Email Outbox
- Email.GetEmailOutboxForRecord(SourceEmailOutbox, TempEmailOutbox);
- Assert.AreEqual(NumberOfEmails, TempEmailOutbox.Count(), 'Email Outbox count is not equal to Number of Emails created.');
-
- for i := 1 to NumberOfEmails do begin
- TempEmailOutbox.SetCurrentKey("Message Id");
- TempEmailOutbox.SetRange("Message Id", MessageIds.Get(i));
- Assert.AreEqual(1, TempEmailOutbox.Count(), 'Did not find the email in Email Outbox');
- end;
- end;
-
- [Test]
- procedure GetEmailOutboxRecordStatus()
- var
- EmailOutbox: Record "Email Outbox";
- EmailMessage: Codeunit "Email Message";
- Any: Codeunit Any;
- EmailTest: Codeunit "Email Test";
- EmailStatus: Enum "Email Status";
- TableId: Integer;
- SystemId: Guid;
- begin
- BindSubscription(EmailTest);
-
- PermissionsMock.Set('Email Edit');
-
- // [Scenario] Emails with source document, GetOutboxEmailRecordStatus will return Outbox Email Status
- // [Given] An Email with table id and source system id
- TableId := Any.IntegerInRange(1, 10000);
- SystemId := Any.GuidValue();
-
- // [When] The email is created and saved as draft
- CreateEmailWithSource(EmailMessage, TableId, SystemId);
-
- // [When] The email is created and saved as draft
- Email.SaveAsDraft(EmailMessage, EmailOutbox);
-
- // [Then] Email Status of created Email Outbox record is equal to GetOutboxEmailRecordStatus result
- EmailStatus := Email.GetOutboxEmailRecordStatus(EmailOutbox."Message Id");
- Assert.AreEqual(EmailStatus, EmailOutbox.Status, 'Email Status should be the same as on Email Outbox record');
- end;
-
- [Test]
- procedure GetSentEmailsForRecordByVariant()
- var
- SentEmail: Record "Sent Email";
- TempSentEmail: Record "Sent Email" temporary;
- EmailAccount: Record "Email Account";
- EmailMessage: Codeunit "Email Message";
- ConnectorMock: Codeunit "Connector Mock";
- Any: Codeunit Any;
- SystemId: Guid;
- TableId, NumberOfEmails, i : Integer;
- MessageIds: List of [Guid];
- begin
- // [Scenario] When successfuly sending an email with source, GetSentEmailsForRecord return related Sent Emails.
- PermissionsMock.Set('Email Edit');
- SentEmail.DeleteAll();
-
- // [Given] An email with source and an email account
- ConnectorMock.Initialize();
- ConnectorMock.AddAccount(EmailAccount);
- TableId := Database::"Email Account";
- SystemId := EmailAccount.SystemId;
- NumberOfEmails := Any.IntegerInRange(2, 5);
-
- for i := 1 to NumberOfEmails do begin
- CreateEmailWithSource(EmailMessage, TableId, SystemId);
- Assert.IsTrue(EmailMessage.Get(EmailMessage.GetId()), 'The email should exist');
- MessageIds.Add(EmailMessage.GetId());
-
- // [When] The email is Sent
- Assert.IsTrue(Email.Send(EmailMessage, EmailAccount), 'Sending an email should have succeeded');
- end;
-
- // [Then] GetSentEmailsForRecord procedure return related Sent Email records
- Email.GetSentEmailsForRecord(EmailAccount, TempSentEmail);
- Assert.AreEqual(NumberOfEmails, TempSentEmail.Count(), 'Sent Emails count is not equal to Number of Emails sent.');
-
- for i := 1 to NumberOfEmails do begin
- TempSentEmail.SetCurrentKey("Message Id");
- TempSentEmail.SetRange("Message Id", MessageIds.Get(i));
- Assert.AreEqual(1, TempSentEmail.Count(), 'Did not find the email in Sent Emails ');
- end;
- end;
-
- local procedure CreateEmail(var EmailMessage: Codeunit "Email Message")
- var
- Any: Codeunit Any;
- begin
- EmailMessage.Create(Any.Email(), Any.UnicodeText(50), Any.UnicodeText(250), true);
- end;
-
- local procedure CreateEmailWithSource(var EmailMessage: Codeunit "Email Message"; TableId: Integer; SystemId: Guid)
- var
- Any: Codeunit Any;
- begin
- EmailMessage.Create(Any.Email(), Any.UnicodeText(50), Any.UnicodeText(250), true);
- Email.AddRelation(EmailMessage, TableId, SystemId, Enum::"Email Relation Type"::"Primary Source", Enum::"Email Relation Origin"::"Compose Context");
- end;
-
- [StrMenuHandler]
- [Scope('OnPrem')]
- procedure CloseEmailEditorHandler(Options: Text[1024]; var Choice: Integer; Instruction: Text[1024])
- begin
- Choice := 1;
- end;
-
- [StrMenuHandler]
- [Scope('OnPrem')]
- procedure OnEmailEditorClose(Options: Text[1024]; var Choice: Integer; Instruction: Text[1024])
- begin
- Assert.AreEqual(InstructionTxt, Instruction, 'Wrong message when closing email editor');
- Assert.AreEqual(OptionsOnClosePageTxt, Options, 'Wrong options when closing the email editor');
-
- Choice := OptionChoice;
- end;
-
- [ModalPageHandler]
- procedure RelationPickerHandler(var EmailRelationPickerTestPage: TestPage "Email Relation Picker")
- begin
- Assert.AreEqual(EmailRelationPickerTestPage."Relation Type".Value(), 'Primary Source', 'No source found on email relation picker page');
-
- ClearLastError();
- EmailRelationPickerTestPage."Source Name".Lookup();
-
- Assert.AreEqual('', GetLastErrorText, 'An error occured - opening email relation from picker');
- end;
-
- [ModalPageHandler]
- procedure RelatedAttachmentsHandler(var RelatedAttachmentsPage: TestPage "Email Related Attachments")
- var
- SourceLabel: Variant;
- begin
- RelatedAttachmentsPage.First();
- DequeueVariable(SourceLabel);
- Assert.AreEqual('Attachment1', RelatedAttachmentsPage.FileName.Value(), 'Wrong Attachment');
- Assert.AreEqual(SourceLabel, RelatedAttachmentsPage.Source.Value(), 'Wrong Attachment');
-
- RelatedAttachmentsPage.OK().Invoke();
- end;
-
- [ModalPageHandler]
- procedure EmailEditorHandler(var EmailEditor: TestPage "Email Editor")
- begin
- Assert.IsTrue(EmailEditor.Account.Enabled(), 'Account field was not enabled');
- Assert.IsTrue(EmailEditor.ToField.Editable(), 'To field was not editable');
- Assert.IsTrue(EmailEditor.CcField.Editable(), 'Cc field was not editable');
- Assert.IsTrue(EmailEditor.BccField.Editable(), 'Bcc field was not editable');
- Assert.IsTrue(EmailEditor.SubjectField.Editable(), 'Subject field was not editable');
- Assert.IsTrue(EmailEditor.BodyField.Editable(), 'Body field was not editable');
- Assert.IsTrue(EmailEditor.Attachments.Upload.Visible(), 'Upload Action is not visible.');
- Assert.IsTrue(EmailEditor.Send.Enabled(), 'Send Action was not enabled.');
- end;
-
- [ModalPageHandler]
- procedure SendEmailEditorHandler(var EmailEditor: TestPage "Email Editor")
- begin
- EmailEditorHandler(EmailEditor);
-
- EmailEditor.Send.Invoke();
- end;
-
- [ModalPageHandler]
- procedure DiscardEmailEditorHandler(var EmailEditor: TestPage "Email Editor")
- begin
- EmailEditorHandler(EmailEditor);
-
- EmailEditor.Discard.Invoke();
- end;
-
-
- [ConfirmHandler]
- procedure ConfirmYes(Question: Text[1024]; var Reply: Boolean);
- begin
- Assert.AreEqual(DiscardEmailQst, Question, 'Wrong confirmation question');
- Reply := true;
- end;
-
- [EventSubscriber(ObjectType::Codeunit, Codeunit::Email, 'OnAfterEmailSent', '', true, true)]
- local procedure OnAfterEmailSentSubscriber(SentEmail: Record "Sent Email")
- begin
- VariableStorage.Enqueue(SentEmail."Message Id");
- VariableStorage.Enqueue(true);
- if ThrowError then
- Error('');
- end;
-
- [EventSubscriber(ObjectType::Codeunit, Codeunit::Email, 'OnAfterEmailSendFailed', '', true, true)]
- local procedure OnAfterEmailSendFailedSubscriber(EmailOutbox: Record "Email Outbox")
- begin
- VariableStorage.Enqueue(EmailOutbox."Message Id");
- VariableStorage.Enqueue(false);
- if ThrowError then
- Error('');
- end;
-
- [EventSubscriber(ObjectType::Codeunit, Codeunit::Email, 'OnShowSource', '', true, true)]
- local procedure OnShowSourceSubscriber(SourceTableId: Integer; SourceSystemId: Guid; var IsHandled: Boolean)
- begin
- IsHandled := true;
- end;
-
- [EventSubscriber(ObjectType::Codeunit, Codeunit::Email, 'OnFindRelatedAttachments', '', true, true)]
- local procedure OnFindRelatedAttachments(SourceTableId: Integer; SourceSystemID: Guid; var EmailRelatedAttachments: Record "Email Related Attachment")
- var
- Any: Codeunit Any;
- begin
- EmailRelatedAttachments."Attachment Name" := 'Attachment1';
- EmailRelatedAttachments."Attachment Table ID" := Any.IntegerInRange(1000);
- EmailRelatedAttachments."Attachment System ID" := System.CreateGuid();
- EmailRelatedAttachments.Insert();
-
- end;
-
- [EventSubscriber(ObjectType::Codeunit, Codeunit::Email, 'OnGetAttachment', '', true, true)]
- local procedure OnGetAttachment(AttachmentTableID: Integer; AttachmentSystemID: Guid; MessageID: Guid)
- var
- EmailMessage: Codeunit "Email Message";
- begin
- EmailMessage.Get(MessageID);
- EmailMessage.AddAttachment('Attachment1', 'text/plain', Base64Convert.ToBase64('Content'));
- end;
-
- procedure ThrowErrorOnAfterSendEmail()
- begin
- ThrowError := true;
- end;
-
- procedure DequeueVariable(var Variable: Variant)
- begin
- VariableStorage.Dequeue(Variable);
- end;
-
- procedure AssertVariableStorageEmpty()
- begin
- VariableStorage.AssertEmpty();
- end;
-
- var
- VariableStorage: Codeunit "Library - Variable Storage";
- InstructionTxt: Label 'The email has not been sent.';
- OptionsOnClosePageTxt: Label 'Keep as draft in Email Outbox,Discard email';
- DiscardEmailQst: Label 'Go ahead and discard?';
- OptionChoice: Integer;
- ThrowError: Boolean;
-}
\ No newline at end of file
diff --git a/src/System Application/Test/File System/src/Mocks/FileAccountsSelectionMock.Codeunit.al b/src/System Application/Test/File System/src/Mocks/FileAccountsSelectionMock.Codeunit.al
index d5f7400867..111bc19247 100644
--- a/src/System Application/Test/File System/src/Mocks/FileAccountsSelectionMock.Codeunit.al
+++ b/src/System Application/Test/File System/src/Mocks/FileAccountsSelectionMock.Codeunit.al
@@ -8,7 +8,7 @@ namespace System.Test.FileSystem;
using System.FileSystem;
///
-/// Used to mock selected email accounts on Email Accounts page.
+/// Used to mock selected file accounts on File Accounts page.
///
codeunit 134697 "File System Acc Selection Mock"
{
From c0276ff2187ab8d118c88110f58eed0821771966 Mon Sep 17 00:00:00 2001
From: Thomas Williamson
Date: Fri, 1 Mar 2024 09:44:19 +0100
Subject: [PATCH 03/43] Add Interface changes
---
.../FileSystemConnector.Interface.al | 8 +---
.../src/FileSystem/FileSystem.Codeunit.al | 13 +-----
.../src/FileSystem/FileSystemImp.Codeunit.al | 46 +++++++++++++++++--
.../src/Lookup/FileAccountBrowser.Page.al | 2 +-
.../src/TestFileSystemConnector.Codeunit.al | 7 +--
5 files changed, 47 insertions(+), 29 deletions(-)
diff --git a/src/System Application/App/File System/src/Connector/FileSystemConnector.Interface.al b/src/System Application/App/File System/src/Connector/FileSystemConnector.Interface.al
index d0a1316638..e104aec01c 100644
--- a/src/System Application/App/File System/src/Connector/FileSystemConnector.Interface.al
+++ b/src/System Application/App/File System/src/Connector/FileSystemConnector.Interface.al
@@ -33,7 +33,7 @@ interface "File System Connector"
/// The file account ID which is used to send out the file.
/// The file path inside the file account.
/// The Stream were the file is read from.
- procedure SetFile(AccountId: Guid; Path: Text; Stream: InStream);
+ procedure CreateFile(AccountId: Guid; Path: Text; Stream: InStream);
///
@@ -99,12 +99,6 @@ interface "File System Connector"
/// The directory path inside the file account.
procedure DeleteDirectory(AccountId: Guid; Path: Text);
- ///
- /// Returns the path separator of the file account.
- ///
- /// The Path separator like / or \
- procedure PathSeparator(): Text;
-
///
/// Gets the file accounts registered for the connector.
///
diff --git a/src/System Application/App/File System/src/FileSystem/FileSystem.Codeunit.al b/src/System Application/App/File System/src/FileSystem/FileSystem.Codeunit.al
index acd2b0eafb..0ac49cdde7 100644
--- a/src/System Application/App/File System/src/FileSystem/FileSystem.Codeunit.al
+++ b/src/System Application/App/File System/src/FileSystem/FileSystem.Codeunit.al
@@ -56,9 +56,9 @@ codeunit 9454 "File System"
/// File Path inside the file account.
/// Stream to store.
[TryFunction]
- procedure SetFile(Path: Text; Stream: InStream)
+ procedure CreateFile(Path: Text; Stream: InStream)
begin
- FileSystemImpl.SetFile(Path, Stream);
+ FileSystemImpl.CreateFile(Path, Stream);
end;
///
@@ -145,15 +145,6 @@ codeunit 9454 "File System"
FileSystemImpl.DeleteDirectory(Path);
end;
- ///
- /// Returns the path separator used by the file account system.
- ///
- ///
- procedure PathSeparator(): Text
- begin
- exit(FileSystemImpl.PathSeparator());
- end;
-
///
/// Combines to paths together.
///
diff --git a/src/System Application/App/File System/src/FileSystem/FileSystemImp.Codeunit.al b/src/System Application/App/File System/src/FileSystem/FileSystemImp.Codeunit.al
index 2286317aeb..3fbbb10640 100644
--- a/src/System Application/App/File System/src/FileSystem/FileSystemImp.Codeunit.al
+++ b/src/System Application/App/File System/src/FileSystem/FileSystemImp.Codeunit.al
@@ -33,75 +33,87 @@ codeunit 9455 "File System Impl."
internal procedure ListFiles(Path: Text; FilePaginationData: Codeunit "File Pagination Data"; var FileAccountContent: Record "File Account Content" temporary)
begin
+ CheckPath(Path);
CheckInitialization();
IFileConnector.ListFiles(CurrFileAccount."Account Id", Path, FilePaginationData, FileAccountContent);
end;
internal procedure GetFile(Path: Text; Stream: InStream)
begin
+ CheckPath(Path);
CheckInitialization();
IFileConnector.GetFile(CurrFileAccount."Account Id", Path, Stream);
end;
- internal procedure SetFile(Path: Text; Stream: InStream)
+ internal procedure CreateFile(Path: Text; Stream: InStream)
begin
+ CheckPath(Path);
CheckInitialization();
- IFileConnector.SetFile(CurrFileAccount."Account Id", Path, Stream);
+ IFileConnector.CreateFile(CurrFileAccount."Account Id", Path, Stream);
end;
internal procedure CopyFile(SourcePath: Text; TargetPath: Text)
begin
+ CheckPath(SourcePath);
+ CheckPath(TargetPath);
CheckInitialization();
IFileConnector.CopyFile(CurrFileAccount."Account Id", SourcePath, TargetPath);
end;
internal procedure MoveFile(SourcePath: Text; TargetPath: Text)
begin
+ CheckPath(SourcePath);
+ CheckPath(TargetPath);
CheckInitialization();
IFileConnector.MoveFile(CurrFileAccount."Account Id", SourcePath, TargetPath);
end;
internal procedure FileExists(Path: Text): Boolean
begin
+ CheckPath(Path);
CheckInitialization();
exit(IFileConnector.FileExists(CurrFileAccount."Account Id", Path));
end;
internal procedure DeleteFile(Path: Text)
begin
+ CheckPath(Path);
CheckInitialization();
IFileConnector.DeleteFile(CurrFileAccount."Account Id", Path);
end;
internal procedure ListDirectories(Path: Text; FilePaginationData: Codeunit "File Pagination Data"; var FileAccountContent: Record "File Account Content" temporary)
begin
+ CheckPath(Path);
CheckInitialization();
IFileConnector.ListDirectories(CurrFileAccount."Account Id", Path, FilePaginationData, FileAccountContent);
end;
internal procedure CreateDirectory(Path: Text)
begin
+ CheckPath(Path);
CheckInitialization();
IFileConnector.CreateDirectory(CurrFileAccount."Account Id", Path);
end;
internal procedure DirectoryExists(Path: Text): Boolean
begin
+ CheckPath(Path);
CheckInitialization();
exit(IFileConnector.DirectoryExists(CurrFileAccount."Account Id", Path));
end;
internal procedure DeleteDirectory(Path: Text)
begin
+ CheckPath(Path);
CheckInitialization();
IFileConnector.DeleteDirectory(CurrFileAccount."Account Id", Path);
end;
internal procedure PathSeparator(): Text
begin
- CheckInitialization();
- exit(IFileConnector.PathSeparator());
+ exit('/');
end;
internal procedure CombinePath(Path: Text; ChildPath: Text): Text
@@ -126,6 +138,7 @@ codeunit 9455 "File System Impl."
FileAccountContent: Record "File Account Content";
FileAccountBrowser: Page "File Account Browser";
begin
+ CheckPath(Path);
CheckInitialization();
FileAccountBrowser.SetPageCaption(DialogTitle);
@@ -146,6 +159,7 @@ codeunit 9455 "File System Impl."
FileAccountContent: Record "File Account Content";
FileAccountBrowser: Page "File Account Browser";
begin
+ CheckPath(Path);
CheckInitialization();
FileAccountBrowser.SetPageCaption(DialogTitle);
@@ -169,6 +183,7 @@ codeunit 9455 "File System Impl."
PleaseProvideFileExtensionErr: Label 'Please provide a valid file extension.';
FileNameTok: Label '%1.%2', Locked = true;
begin
+ CheckPath(Path);
CheckInitialization();
if FileExtension = '' then
@@ -205,4 +220,27 @@ codeunit 9455 "File System Impl."
Error(NotInitializedErr);
end;
+
+ local procedure CheckPath(Path: Text)
+ var
+ InvalidChars: Text;
+ InvalidChar: Char;
+ PathCannotStartWithSlashErr: Label 'The path %1 can not start with /.', Comment = '%1 - Path';
+
+ begin
+ if Path.StartsWith('/') then
+ Error(PathCannotStartWithSlashErr, Path);
+
+ InvalidChars := '"''<>\|';
+ foreach InvalidChar in InvalidChars do
+ CheckPath(Path, InvalidChar);
+ end;
+
+ local procedure CheckPath(Path: Text; InvalidChar: Char)
+ var
+ InvalidPathErr: Label 'The path %1 contains the invalid character %2.', Comment = '%1 - Path, %2 - Invalid Character';
+ begin
+ if Path.Contains(InvalidChar) then
+ Error(InvalidPathErr, Path, InvalidChar);
+ end;
}
\ No newline at end of file
diff --git a/src/System Application/App/File System/src/Lookup/FileAccountBrowser.Page.al b/src/System Application/App/File System/src/Lookup/FileAccountBrowser.Page.al
index dcec939279..536994d999 100644
--- a/src/System Application/App/File System/src/Lookup/FileAccountBrowser.Page.al
+++ b/src/System Application/App/File System/src/Lookup/FileAccountBrowser.Page.al
@@ -251,7 +251,7 @@ page 9455 "File Account Browser"
if not UploadIntoStream(UploadDialogTxt, '', '', FromFile, Stream) then
exit;
- FileSystem.SetFile(FileSystem.CombinePath(CurrPath, FromFile), Stream);
+ FileSystem.CreateFile(FileSystem.CombinePath(CurrPath, FromFile), Stream);
end;
local procedure CreateDirectory()
diff --git a/src/System Application/Test Library/File System/src/TestFileSystemConnector.Codeunit.al b/src/System Application/Test Library/File System/src/TestFileSystemConnector.Codeunit.al
index 75d8e17e58..7c9dc820d2 100644
--- a/src/System Application/Test Library/File System/src/TestFileSystemConnector.Codeunit.al
+++ b/src/System Application/Test Library/File System/src/TestFileSystemConnector.Codeunit.al
@@ -27,7 +27,7 @@ codeunit 80202 "Test File System Connector" implements "File System Connector"
end;
- procedure SetFile(AccountId: Guid; Path: Text; Stream: InStream);
+ procedure CreateFile(AccountId: Guid; Path: Text; Stream: InStream);
begin
end;
@@ -72,11 +72,6 @@ codeunit 80202 "Test File System Connector" implements "File System Connector"
end;
- procedure PathSeparator(): Text;
- begin
-
- end;
-
procedure GetAccounts(var Accounts: Record "File Account")
begin
ConnectorMock.GetAccounts(Accounts);
From 7945909434316658a0787dd5f5211425ea042e56 Mon Sep 17 00:00:00 2001
From: Thomas Williamson
Date: Fri, 1 Mar 2024 14:40:14 +0100
Subject: [PATCH 04/43] Fix Account Browser
---
.../src/FileSystem/FileSystemImp.Codeunit.al | 5 +-
.../src/Lookup/FileAccountBrowser.Page.al | 62 ++++++++-----------
2 files changed, 30 insertions(+), 37 deletions(-)
diff --git a/src/System Application/App/File System/src/FileSystem/FileSystemImp.Codeunit.al b/src/System Application/App/File System/src/FileSystem/FileSystemImp.Codeunit.al
index 3fbbb10640..745636c19d 100644
--- a/src/System Application/App/File System/src/FileSystem/FileSystemImp.Codeunit.al
+++ b/src/System Application/App/File System/src/FileSystem/FileSystemImp.Codeunit.al
@@ -129,8 +129,9 @@ codeunit 9455 "File System Impl."
internal procedure GetParentPath(Path: Text) ParentPath: Text
begin
- if (Path.TrimEnd(PathSeparator()).Contains(PathSeparator())) then
- ParentPath := Path.TrimEnd(PathSeparator()).Substring(1, Path.LastIndexOf(PathSeparator()));
+ Path := Path.TrimEnd(PathSeparator());
+ if Path.TrimEnd(PathSeparator()).Contains(PathSeparator()) then
+ ParentPath := Path.Substring(1, Path.LastIndexOf(PathSeparator()));
end;
internal procedure SelectFolderUI(Path: Text; DialogTitle: Text): Text
diff --git a/src/System Application/App/File System/src/Lookup/FileAccountBrowser.Page.al b/src/System Application/App/File System/src/Lookup/FileAccountBrowser.Page.al
index 536994d999..75acbd0b49 100644
--- a/src/System Application/App/File System/src/Lookup/FileAccountBrowser.Page.al
+++ b/src/System Application/App/File System/src/Lookup/FileAccountBrowser.Page.al
@@ -9,6 +9,7 @@ page 9455 "File Account Browser"
{
Caption = 'File Account Browser';
PageType = List;
+ ApplicationArea = All;
SourceTable = "File Account Content";
ModifyAllowed = false;
InsertAllowed = false;
@@ -19,26 +20,33 @@ page 9455 "File Account Browser"
{
area(content)
{
+ field(CurrPathField; CurrPath)
+ {
+ Caption = 'Path';
+ ShowCaption = false;
+ Editable = false;
+ }
repeater(General)
{
field(Name; Rec.Name)
{
DrillDown = true;
- ApplicationArea = All;
ToolTip = 'Specifies the value of the Name field.';
trigger OnDrillDown()
begin
- if Rec.Type = Rec.Type::Directory then
- BrowseFolder(Rec)
- else
- if not IsInLookupMode then
+ case true of
+ (Rec.Name = '..'):
+ BrowseFolder(Rec."Parent Directory");
+ (Rec.Type = Rec.Type::Directory):
+ BrowseFolder(Rec);
+ (not IsInLookupMode):
DownloadFile(Rec);
+ end;
end;
}
field("Type"; Rec."Type")
{
- ApplicationArea = All;
ToolTip = 'Specifies the value of the Type field.';
}
}
@@ -51,7 +59,6 @@ page 9455 "File Account Browser"
field(SaveFileNameField; SaveFileName)
{
- ApplicationArea = All;
Caption = 'Filename';
}
}
@@ -62,31 +69,12 @@ page 9455 "File Account Browser"
{
area(Promoted)
{
- actionref(UpRef; Up) { }
actionref(UploadRef; Upload) { }
actionref(CreateDirectoryRef; "Create Directory") { }
actionref(DeleteRef; Delete) { }
}
area(Processing)
{
- action(Up)
- {
- Caption = 'Up';
- ApplicationArea = All;
- Image = MoveUp;
- Enabled = ParentFolderExists;
-
- trigger OnAction()
- var
- Path: Text;
- begin
- if CurrPath = '' then
- exit;
-
- Path := FileSystem.GetParentPath(CurrPath);
- BrowseFolder(Path);
- end;
- }
action(Upload)
{
Caption = 'Upload';
@@ -222,7 +210,7 @@ page 9455 "File Account Browser"
var
FilePaginationData: Codeunit "File Pagination Data";
begin
- CurrPath := Path;
+ CurrPath := Path.TrimEnd('/');
ParentFolderExists := Path <> '';
Rec.DeleteAll();
@@ -286,14 +274,18 @@ page 9455 "File Account Browser"
if CurrFileFilter <> '' then
FileAccountContent.SetFilter(Name, CurrFileFilter);
- if not FileAccountContent.FindSet() then
- exit;
-
- repeat
- Rec.Init();
- Rec.TransferFields(FileAccountContent);
- Rec.Insert();
- until FileAccountContent.Next() = 0;
+ if FileAccountContent.FindSet() then
+ repeat
+ Rec.Init();
+ Rec.TransferFields(FileAccountContent);
+ Rec.Insert();
+ until FileAccountContent.Next() = 0;
+
+ Rec.Init();
+ Rec.Name := '..';
+ Rec.Type := Rec.Type::Directory;
+ Rec."Parent Directory" := FileSystem.GetParentPath(CurrPath);
+ Rec.Insert();
end;
local procedure DeleteFileOrDirectory()
From 692b8b7d85ca16ab36df463099ab9aa24309a6c1 Mon Sep 17 00:00:00 2001
From: Thomas Williamson
Date: Fri, 1 Mar 2024 16:04:44 +0100
Subject: [PATCH 05/43] Change application are to new logic
---
.../src/Account/FileAccountWizard.Page.al | 18 +----
.../src/Account/FileAccounts.Page.al | 68 ++++++++++---------
.../src/Lookup/FileAccountBrowser.Page.al | 3 -
.../src/Scenario/FileScenarioSetup.Page.al | 32 ++++-----
.../src/Scenario/FileScenariosFactBox.Page.al | 2 +-
.../Scenario/FileScenariosForAccount.Page.al | 2 +-
6 files changed, 57 insertions(+), 68 deletions(-)
diff --git a/src/System Application/App/File System/src/Account/FileAccountWizard.Page.al b/src/System Application/App/File System/src/Account/FileAccountWizard.Page.al
index a1f57f8cc4..dc4f4e302c 100644
--- a/src/System Application/App/File System/src/Account/FileAccountWizard.Page.al
+++ b/src/System Application/App/File System/src/Account/FileAccountWizard.Page.al
@@ -76,7 +76,6 @@ page 9451 "File Account Wizard"
field(LearnMoreHeader; LearnMoreTok)
{
- ApplicationArea = All;
Editable = false;
ShowCaption = false;
Caption = ' ';
@@ -118,7 +117,6 @@ page 9451 "File Account Wizard"
label("Specify the type of file account to add")
{
Caption = 'Specify the type of file account to add';
- ApplicationArea = All;
}
repeater(Connectors)
@@ -130,7 +128,6 @@ page 9451 "File Account Wizard"
field(Logo; Rec.Logo)
{
- ApplicationArea = All;
Caption = ' ';
Editable = false;
Visible = ChooseConnectorVisible;
@@ -141,7 +138,6 @@ page 9451 "File Account Wizard"
field(Name; Rec.Connector)
{
- ApplicationArea = All;
Caption = 'Account Type';
ToolTip = 'Specifies the type of the account you want to create.';
Editable = false;
@@ -149,7 +145,6 @@ page 9451 "File Account Wizard"
field(Details; Rec.Description)
{
- ApplicationArea = All;
Caption = 'Details';
ToolTip = 'Specifies more details about the account type.';
Editable = false;
@@ -163,19 +158,16 @@ page 9451 "File Account Wizard"
Visible = ChooseConnectorVisible and not ConnectorsAvailable;
label(NoConnectorsAvailable)
{
- ApplicationArea = All;
Caption = 'There are no file apps available. To use this feature you must install an file app.';
}
label(NoConnectorsAvailable2)
{
- ApplicationArea = All;
Caption = 'File apps are available in Extension Management and AppSource.';
}
field(ExtensionManagement; ExtensionManagementTok)
{
- ApplicationArea = All;
Editable = false;
ShowCaption = false;
Caption = ' ';
@@ -189,7 +181,6 @@ page 9451 "File Account Wizard"
field(AppSource; AppSourceTok)
{
- ApplicationArea = All;
Editable = false;
ShowCaption = false;
Visible = AppSourceAvailable;
@@ -198,11 +189,8 @@ page 9451 "File Account Wizard"
trigger OnDrillDown()
begin
- //FIXME
- /*
AppSource := AppSource.Create();
AppSource.ShowAppSource();
- */
end;
}
@@ -376,7 +364,7 @@ page 9451 "File Account Wizard"
SetAsDefault := true;
ConnectorsAvailable := Rec.FindFirst(); // Set the focus on the first record
- AppSourceAvailable := false; //FIXME AppSource.IsAvailable();
+ AppSourceAvailable := AppSource.IsAvailable();
LoadTopBanners();
end;
@@ -496,8 +484,8 @@ page 9451 "File Account Wizard"
RegisteredAccount: Record "File Account";
MediaResourcesStandard: Record "Media Resources";
MediaResourcesDone: Record "Media Resources";
- //FIXME [RunOnClient]
- //FIXME AppSource: DotNet AppSource;
+ [RunOnClient]
+ AppSource: DotNet AppSource;
Step: Option Welcome,"Choose Connector","Register Account",Done;
RateLimit: Integer;
AppSourceTok: Label 'AppSource';
diff --git a/src/System Application/App/File System/src/Account/FileAccounts.Page.al b/src/System Application/App/File System/src/Account/FileAccounts.Page.al
index 9510fb0075..e8cd36e864 100644
--- a/src/System Application/App/File System/src/Account/FileAccounts.Page.al
+++ b/src/System Application/App/File System/src/Account/FileAccounts.Page.al
@@ -14,11 +14,9 @@ page 9450 "File Accounts"
{
PageType = List;
Caption = 'File Accounts';
- ApplicationArea = All;
UsageCategory = Administration;
SourceTable = "File Account";
SourceTableTemporary = true;
- PromotedActionCategories = 'New,Process,Report,Navigate';
InsertAllowed = false;
ModifyAllowed = false;
DeleteAllowed = false;
@@ -37,7 +35,6 @@ page 9450 "File Accounts"
FreezeColumn = NameField;
field(LogoField; Rec.LogoBlob)
{
- ApplicationArea = All;
ShowCaption = false;
Caption = ' ';
Visible = ShowLogo;
@@ -47,7 +44,6 @@ page 9450 "File Accounts"
field(NameField; Rec.Name)
{
- ApplicationArea = All;
ToolTip = 'Specifies the name of the account.';
Visible = not IsInLookupMode;
@@ -59,14 +55,12 @@ page 9450 "File Accounts"
field(NameFieldLookup; Rec.Name)
{
- ApplicationArea = All;
ToolTip = 'Specifies the name of the account.';
Visible = IsInLookupMode;
}
field(DefaultField; DefaultTxt)
{
- ApplicationArea = All;
Caption = 'Default';
ToolTip = 'Specifies whether the file account will be used for all scenarios for which an account is not specified. You must have a default file account, even if you have only one account.';
Visible = not IsInLookupMode;
@@ -74,7 +68,6 @@ page 9450 "File Accounts"
field(FileConnector; Rec.Connector)
{
- ApplicationArea = All;
ToolTip = 'Specifies the type of file extension that the account is added to.';
Visible = false;
}
@@ -87,7 +80,6 @@ page 9450 "File Accounts"
{
Caption = 'File Scenarios';
SubPageLink = "Account Id" = field("Account Id"), Connector = field(Connector), Scenario = filter(<> 0); // Do not show Default scenario
- ApplicationArea = All;
}
}
}
@@ -98,7 +90,6 @@ page 9450 "File Accounts"
{
action(View)
{
- ApplicationArea = All;
Image = View;
ToolTip = 'View settings for the file account.';
ShortcutKey = return;
@@ -112,10 +103,6 @@ page 9450 "File Accounts"
action(AddAccount)
{
- ApplicationArea = All;
- Promoted = true;
- PromotedOnly = true;
- PromotedCategory = New;
Image = Add;
Caption = 'Add an file account';
ToolTip = 'Add an file account.';
@@ -134,15 +121,10 @@ page 9450 "File Accounts"
{
action(MakeDefault)
{
- ApplicationArea = All;
Image = Default;
Caption = 'Set as default';
ToolTip = 'Mark the selected file account as the default account. This account will be used for all scenarios for which an account is not specified.';
Visible = (not IsInLookupMode) and CanUserManageFileSetup;
- Promoted = true;
- PromotedOnly = true;
- PromotedCategory = Process;
- PromotedIsBig = true;
Scope = Repeater;
Enabled = not IsDefault;
@@ -156,15 +138,10 @@ page 9450 "File Accounts"
}
action(BrowseAccount)
{
- ApplicationArea = All;
Image = SelectField;
Caption = 'Browse Account';
ToolTip = 'Opens a File Browser and shows the content of the selected account.';
Visible = (not IsInLookupMode) and CanUserManageFileSetup;
- Promoted = true;
- PromotedOnly = true;
- PromotedCategory = Process;
- PromotedIsBig = true;
Scope = Repeater;
trigger OnAction()
@@ -178,10 +155,6 @@ page 9450 "File Accounts"
action(Delete)
{
- ApplicationArea = All;
- Promoted = true;
- PromotedOnly = true;
- PromotedCategory = Process;
Image = Delete;
Caption = 'Delete file account';
ToolTip = 'Delete the file account.';
@@ -204,10 +177,6 @@ page 9450 "File Accounts"
{
action(FileScenarioSetup)
{
- ApplicationArea = All;
- Promoted = true;
- PromotedOnly = true;
- PromotedCategory = Category4;
Image = Answers;
Caption = 'File Scenarios';
ToolTip = 'Assign scenarios to the file accounts.';
@@ -222,6 +191,43 @@ page 9450 "File Accounts"
end;
}
}
+ area(Promoted)
+ {
+ group(Category_New)
+ {
+ Caption = 'New';
+
+ actionref(AddAccount_Promoted; AddAccount)
+ {
+ }
+ }
+ group(Category_Process)
+ {
+ Caption = 'Process';
+
+ actionref(MakeDefault_Promoted; MakeDefault)
+ {
+ }
+ actionref(BrowseAccount_Promoted; BrowseAccount)
+ {
+ }
+ actionref(Delete_Promoted; Delete)
+ {
+ }
+ }
+ group(Category_Report)
+ {
+ Caption = 'Report';
+ }
+ group(Category_Category4)
+ {
+ Caption = 'Navigate';
+
+ actionref(FileScenarioSetup_Promoted; FileScenarioSetup)
+ {
+ }
+ }
+ }
}
trigger OnOpenPage()
diff --git a/src/System Application/App/File System/src/Lookup/FileAccountBrowser.Page.al b/src/System Application/App/File System/src/Lookup/FileAccountBrowser.Page.al
index 75acbd0b49..5a14c083a9 100644
--- a/src/System Application/App/File System/src/Lookup/FileAccountBrowser.Page.al
+++ b/src/System Application/App/File System/src/Lookup/FileAccountBrowser.Page.al
@@ -78,7 +78,6 @@ page 9455 "File Account Browser"
action(Upload)
{
Caption = 'Upload';
- ApplicationArea = All;
Image = Import;
Ellipsis = true;
Visible = not IsInLookupMode;
@@ -93,7 +92,6 @@ page 9455 "File Account Browser"
action("Create Directory")
{
Caption = 'Create Directory';
- ApplicationArea = All;
Image = Bin;
Ellipsis = true;
Visible = not IsInLookupMode;
@@ -108,7 +106,6 @@ page 9455 "File Account Browser"
action(Delete)
{
Caption = 'Delete';
- ApplicationArea = All;
Image = Delete;
Ellipsis = true;
Visible = not IsInLookupMode;
diff --git a/src/System Application/App/File System/src/Scenario/FileScenarioSetup.Page.al b/src/System Application/App/File System/src/Scenario/FileScenarioSetup.Page.al
index 29a64a1b3f..22d61e420b 100644
--- a/src/System Application/App/File System/src/Scenario/FileScenarioSetup.Page.al
+++ b/src/System Application/App/File System/src/Scenario/FileScenarioSetup.Page.al
@@ -36,7 +36,6 @@ page 9452 "File Scenario Setup"
field(Name; Rec."Display Name")
{
- ApplicationArea = All;
Caption = 'Scenarios by file accounts';
ToolTip = 'Specifies the scenarios that are using the file account.';
Editable = false;
@@ -45,7 +44,6 @@ page 9452 "File Scenario Setup"
field(Default; DefaultTxt)
{
- ApplicationArea = All;
Caption = 'Default';
ToolTip = 'Specifies whether this is the default account to use for scenarios when no other account is specified.';
StyleExpr = Style;
@@ -64,14 +62,9 @@ page 9452 "File Scenario Setup"
{
Visible = (TypeOfEntry = TypeOfEntry::Account) and CanUserManageFileSetup;
- ApplicationArea = All;
Caption = 'Assign scenarios';
ToolTip = 'Assign file scenarios for the selected file account. When assigned, everyone will use the account for the scenario. For example, if you assign the Sales Order scenario, everyone will use the account to send sales orders.';
Image = NewDocument;
- Promoted = true;
- PromotedOnly = true;
- PromotedCategory = Process;
- PromotedIsBig = true;
Scope = Repeater;
trigger OnAction()
@@ -91,14 +84,9 @@ page 9452 "File Scenario Setup"
{
Visible = (TypeOfEntry = TypeOfEntry::Scenario) and CanUserManageFileSetup;
- ApplicationArea = All;
Caption = 'Reassign';
ToolTip = 'Reassign the selected scenarios to another file account.';
Image = Change;
- Promoted = true;
- PromotedOnly = true;
- PromotedCategory = Process;
- PromotedIsBig = true;
Scope = Repeater;
trigger OnAction()
@@ -116,14 +104,9 @@ page 9452 "File Scenario Setup"
{
Visible = (TypeOfEntry = TypeOfEntry::Scenario) and CanUserManageFileSetup;
- ApplicationArea = All;
Caption = 'Unassign';
ToolTip = 'Unassign the selected scenarios. Afterward, the default file account will be used to send files for the scenarios.';
Image = Delete;
- Promoted = true;
- PromotedOnly = true;
- PromotedCategory = Process;
- PromotedIsBig = true;
Scope = Repeater;
trigger OnAction()
@@ -138,6 +121,21 @@ page 9452 "File Scenario Setup"
}
}
}
+ area(Promoted)
+ {
+ group(Category_Process)
+ {
+ actionref(AddScenario_Promoted; AddScenario)
+ {
+ }
+ actionref(ChangeAccount_Promoted; ChangeAccount)
+ {
+ }
+ actionref(Unassign_Promoted; Unassign)
+ {
+ }
+ }
+ }
}
trigger OnOpenPage()
diff --git a/src/System Application/App/File System/src/Scenario/FileScenariosFactBox.Page.al b/src/System Application/App/File System/src/Scenario/FileScenariosFactBox.Page.al
index 871119cebd..d803810eec 100644
--- a/src/System Application/App/File System/src/Scenario/FileScenariosFactBox.Page.al
+++ b/src/System Application/App/File System/src/Scenario/FileScenariosFactBox.Page.al
@@ -11,6 +11,7 @@ namespace System.FileSystem;
page 9453 "File Scenarios FactBox"
{
PageType = ListPart;
+ ApplicationArea = All;
Extensible = false;
SourceTable = "File Scenario";
InsertAllowed = false;
@@ -29,7 +30,6 @@ page 9453 "File Scenarios FactBox"
{
field(Name; Format(Rec.Scenario))
{
- ApplicationArea = All;
ToolTip = 'The file scenario.';
Caption = 'File scenario';
Editable = false;
diff --git a/src/System Application/App/File System/src/Scenario/FileScenariosForAccount.Page.al b/src/System Application/App/File System/src/Scenario/FileScenariosForAccount.Page.al
index d8691c5e8a..1544ade054 100644
--- a/src/System Application/App/File System/src/Scenario/FileScenariosForAccount.Page.al
+++ b/src/System Application/App/File System/src/Scenario/FileScenariosForAccount.Page.al
@@ -11,6 +11,7 @@ namespace System.FileSystem;
page 9454 "File Scenarios for Account"
{
PageType = List;
+ ApplicationArea = All;
Extensible = false;
SourceTable = "File Account Scenario";
InsertAllowed = false;
@@ -28,7 +29,6 @@ page 9454 "File Scenarios for Account"
{
field(Name; Rec."Display Name")
{
- ApplicationArea = All;
ToolTip = 'The file scenario.';
Caption = 'File scenario';
Editable = false;
From 1277528c0b3ceade97d227c4c782abc1cf4f08f9 Mon Sep 17 00:00:00 2001
From: Thomas Williamson
Date: Fri, 1 Mar 2024 17:43:58 +0100
Subject: [PATCH 06/43] Fix first batch of code review suggestions
---
.../FileSystemAdmin.PermissionSet.al | 11 ++-
.../FileSystemEdit.PermissionSet.al | 4 +-
.../FileSystemObjects.PermissionSetExt.al | 34 ---------
.../src/Account/FileAccount.Codeunit.al | 2 +
.../src/Account/FileAccountImpl.Codeunit.al | 28 +++----
.../src/Account/FileAccountWizard.Page.al | 2 +
.../src/Account/FileAccounts.Page.al | 2 +
.../src/FileSystem/FileSystem.Codeunit.al | 3 +
.../src/FileSystem/FileSystemImp.Codeunit.al | 76 ++++++++++---------
.../src/Lookup/FileAccountBrowser.Page.al | 2 +
.../src/Lookup/FilePaginationData.Codeunit.al | 3 +
.../src/Lookup/FolderNameInput.Page.al | 2 +
.../src/Scenario/FileScenario.Codeunit.al | 3 +
.../src/Scenario/FileScenario.Table.al | 2 +
.../src/Scenario/FileScenarioSetup.Page.al | 2 +
.../src/Scenario/FileScenariosFactBox.Page.al | 2 +
.../Scenario/FileScenariosForAccount.Page.al | 2 +
17 files changed, 87 insertions(+), 93 deletions(-)
delete mode 100644 src/System Application/App/File System/permissions/FileSystemObjects.PermissionSetExt.al
diff --git a/src/System Application/App/File System/permissions/FileSystemAdmin.PermissionSet.al b/src/System Application/App/File System/permissions/FileSystemAdmin.PermissionSet.al
index 26d6e72537..b3006b9973 100644
--- a/src/System Application/App/File System/permissions/FileSystemAdmin.PermissionSet.al
+++ b/src/System Application/App/File System/permissions/FileSystemAdmin.PermissionSet.al
@@ -14,10 +14,9 @@ permissionset 9450 "File System - Admin"
IncludedPermissionSets = "File System - Edit";
Permissions =
- tabledata "File Account" = RMID,
- tabledata "File System Connector" = RMID,
- tabledata "File System Connector Logo" = RMID,
- tabledata "File Account Scenario" = RMID,
- tabledata "File Scenario" = RMID,
- tabledata "File Account Content" = RMID;
+ tabledata "File System Connector" = RIMD,
+ tabledata "File System Connector Logo" = RIMD,
+ tabledata "File Account Scenario" = RIMD,
+ tabledata "File Scenario" = RIMD,
+ tabledata "File Account Content" = RIMD;
}
diff --git a/src/System Application/App/File System/permissions/FileSystemEdit.PermissionSet.al b/src/System Application/App/File System/permissions/FileSystemEdit.PermissionSet.al
index 8f27dfc1fb..d0f2bffde8 100644
--- a/src/System Application/App/File System/permissions/FileSystemEdit.PermissionSet.al
+++ b/src/System Application/App/File System/permissions/FileSystemEdit.PermissionSet.al
@@ -12,9 +12,7 @@ permissionset 9451 "File System - Read"
Access = Internal;
Assignable = false;
- IncludedPermissionSets = "File System - Objects";
-
- Permissions = tabledata "File Account" = r,
+ Permissions =
tabledata "File System Connector" = r,
tabledata "File System Connector Logo" = r,
tabledata "File Account Scenario" = r,
diff --git a/src/System Application/App/File System/permissions/FileSystemObjects.PermissionSetExt.al b/src/System Application/App/File System/permissions/FileSystemObjects.PermissionSetExt.al
deleted file mode 100644
index 43ad58750a..0000000000
--- a/src/System Application/App/File System/permissions/FileSystemObjects.PermissionSetExt.al
+++ /dev/null
@@ -1,34 +0,0 @@
-// ------------------------------------------------------------------------------------------------
-// Copyright (c) Microsoft Corporation. All rights reserved.
-// Licensed under the MIT License. See License.txt in the project root for license information.
-// ------------------------------------------------------------------------------------------------
-
-namespace System.FileSystem;
-
-permissionset 9452 "File System - Objects"
-{
- Access = Internal;
- Assignable = false;
-
- Permissions =
- table "File Account" = X,
- table "File System Connector" = X,
- table "File System Connector Logo" = X,
- table "File Account Scenario" = X,
- table "File Scenario" = X,
- table "File Account Content" = X,
- codeunit "File Account" = X,
- codeunit "File Account Impl." = X,
- codeunit "File Scenario" = X,
- codeunit "File Pagination Data" = X,
- codeunit "File System Impl." = X,
- codeunit "File System" = X,
- codeunit "File Scenario Impl." = X,
- page "File Accounts" = X,
- page "File Account Wizard" = X,
- page "Folder Name Input" = X,
- page "File Scenarios FactBox" = X,
- page "File Scenarios for Account" = X,
- page "File Scenario Setup" = X,
- page "File Account Browser" = X;
-}
diff --git a/src/System Application/App/File System/src/Account/FileAccount.Codeunit.al b/src/System Application/App/File System/src/Account/FileAccount.Codeunit.al
index 1d97060fcf..5165b56b2b 100644
--- a/src/System Application/App/File System/src/Account/FileAccount.Codeunit.al
+++ b/src/System Application/App/File System/src/Account/FileAccount.Codeunit.al
@@ -12,6 +12,8 @@ namespace System.FileSystem;
codeunit 9450 "File Account"
{
Access = Public;
+ InherentPermissions = X;
+ InherentEntitlements = X;
///
/// Gets all of the file accounts registered in Business Central.
diff --git a/src/System Application/App/File System/src/Account/FileAccountImpl.Codeunit.al b/src/System Application/App/File System/src/Account/FileAccountImpl.Codeunit.al
index f7dae371f0..58768ea4dd 100644
--- a/src/System Application/App/File System/src/Account/FileAccountImpl.Codeunit.al
+++ b/src/System Application/App/File System/src/Account/FileAccountImpl.Codeunit.al
@@ -19,17 +19,17 @@ codeunit 9451 "File Account Impl."
procedure GetAllAccounts(LoadLogos: Boolean; var TempFileAccount: Record "File Account" temporary)
var
FileAccounts: Record "File Account";
- IFileConnector: Interface "File System Connector";
+ FileSystemConnector: Interface "File System Connector";
Connector: Enum "File System Connector";
begin
TempFileAccount.Reset();
TempFileAccount.DeleteAll();
foreach Connector in Connector.Ordinals do begin
- IFileConnector := Connector;
+ FileSystemConnector := Connector;
FileAccounts.DeleteAll();
- IFileConnector.GetAccounts(FileAccounts);
+ FileSystemConnector.GetAccounts(FileAccounts);
if FileAccounts.FindSet() then
repeat
@@ -54,7 +54,7 @@ codeunit 9451 "File Account Impl."
CurrentDefaultFileAccount: Record "File Account";
ConfirmManagement: Codeunit "Confirm Management";
FileScenario: Codeunit "File Scenario";
- FileConnector: Interface "File System Connector";
+ FileSystemConnector: Interface "File System Connector";
begin
CheckPermissions();
@@ -72,15 +72,15 @@ codeunit 9451 "File Account Impl."
// Check to validate that the connector is still installed
// The connector could have been uninstalled by another user/session
if IsValidConnector(FileAccountsToDelete.Connector) then begin
- FileConnector := FileAccountsToDelete.Connector;
- FileConnector.DeleteAccount(FileAccountsToDelete."Account Id");
+ FileSystemConnector := FileAccountsToDelete.Connector;
+ FileSystemConnector.DeleteAccount(FileAccountsToDelete."Account Id");
end;
until FileAccountsToDelete.Next() = 0;
- HandleDefaultAccountDeletion(CurrentDefaultFileAccount."Account Id", CurrentDefaultFileAccount.Connector);
+ DefaultAccountDeletion(CurrentDefaultFileAccount."Account Id", CurrentDefaultFileAccount.Connector);
end;
- local procedure HandleDefaultAccountDeletion(CurrentDefaultAccountId: Guid; Connector: Enum "File System Connector")
+ local procedure DefaultAccountDeletion(CurrentDefaultAccountId: Guid; Connector: Enum "File System Connector")
var
AllFileAccounts: Record "File Account";
NewDefaultFileAccount: Record "File Account";
@@ -167,14 +167,14 @@ codeunit 9451 "File Account Impl."
var
Base64Convert: Codeunit "Base64 Convert";
ConnectorInterface: Interface "File System Connector";
- Connector: Enum "File System Connector";
+ FileSystemConnector: Enum "File System Connector";
ConnectorLogoBase64: Text;
OutStream: Outstream;
begin
- foreach Connector in Enum::"File System Connector".Ordinals() do begin
- ConnectorInterface := Connector;
+ foreach FileSystemConnector in Enum::"File System Connector".Ordinals() do begin
+ ConnectorInterface := FileSystemConnector;
ConnectorLogoBase64 := ConnectorInterface.GetLogoAsBase64();
- FileConnector.Connector := Connector;
+ FileConnector.Connector := FileSystemConnector;
FileConnector.Description := ConnectorInterface.GetDescription();
if ConnectorLogoBase64 <> '' then begin
FileConnector.Logo.CreateOutStream(OutStream);
@@ -221,13 +221,13 @@ codeunit 9451 "File Account Impl."
Error(CannotManageSetupErr);
end;
- local procedure ImportLogoBlob(var FileAccount: Record "File Account"; Connector: Interface "File System Connector")
+ local procedure ImportLogoBlob(var FileAccount: Record "File Account"; FileSystemConnector: Interface "File System Connector")
var
Base64Convert: Codeunit "Base64 Convert";
ConnectorLogoBase64: Text;
OutStream: Outstream;
begin
- ConnectorLogoBase64 := Connector.GetLogoAsBase64();
+ ConnectorLogoBase64 := FileSystemConnector.GetLogoAsBase64();
if ConnectorLogoBase64 <> '' then begin
FileAccount.LogoBlob.CreateOutStream(OutStream);
diff --git a/src/System Application/App/File System/src/Account/FileAccountWizard.Page.al b/src/System Application/App/File System/src/Account/FileAccountWizard.Page.al
index dc4f4e302c..3cd716b6db 100644
--- a/src/System Application/App/File System/src/Account/FileAccountWizard.Page.al
+++ b/src/System Application/App/File System/src/Account/FileAccountWizard.Page.al
@@ -26,6 +26,8 @@ page 9451 "File Account Wizard"
Editable = true;
ShowFilter = false;
LinksAllowed = false;
+ InherentPermissions = X;
+ InherentEntitlements = X;
Permissions = tabledata Media = r,
tabledata "Media Resources" = r;
diff --git a/src/System Application/App/File System/src/Account/FileAccounts.Page.al b/src/System Application/App/File System/src/Account/FileAccounts.Page.al
index e8cd36e864..bdb4739d29 100644
--- a/src/System Application/App/File System/src/Account/FileAccounts.Page.al
+++ b/src/System Application/App/File System/src/Account/FileAccounts.Page.al
@@ -24,6 +24,8 @@ page 9450 "File Accounts"
ShowFilter = false;
LinksAllowed = false;
RefreshOnActivate = true;
+ InherentPermissions = X;
+ InherentEntitlements = X;
layout
{
diff --git a/src/System Application/App/File System/src/FileSystem/FileSystem.Codeunit.al b/src/System Application/App/File System/src/FileSystem/FileSystem.Codeunit.al
index 0ac49cdde7..15b179c2c3 100644
--- a/src/System Application/App/File System/src/FileSystem/FileSystem.Codeunit.al
+++ b/src/System Application/App/File System/src/FileSystem/FileSystem.Codeunit.al
@@ -7,6 +7,9 @@ namespace System.FileSystem;
codeunit 9454 "File System"
{
+ InherentPermissions = X;
+ InherentEntitlements = X;
+
var
FileSystemImpl: Codeunit "File System Impl.";
diff --git a/src/System Application/App/File System/src/FileSystem/FileSystemImp.Codeunit.al b/src/System Application/App/File System/src/FileSystem/FileSystemImp.Codeunit.al
index 745636c19d..020dbf7a57 100644
--- a/src/System Application/App/File System/src/FileSystem/FileSystemImp.Codeunit.al
+++ b/src/System Application/App/File System/src/FileSystem/FileSystemImp.Codeunit.al
@@ -7,12 +7,16 @@ namespace System.FileSystem;
codeunit 9455 "File System Impl."
{
+ Access = Internal;
+ InherentPermissions = X;
+ InherentEntitlements = X;
+
var
- IFileConnector: Interface "File System Connector";
+ FileSystemConnector: Interface "File System Connector";
CurrFileAccount: Record "File Account";
- Initialized: Boolean;
+ IsInitialized: Boolean;
- internal procedure Initialize(Scenario: Enum "File Scenario")
+ procedure Initialize(Scenario: Enum "File Scenario")
var
FileAccount: Record "File Account";
FileScenario: Codeunit "File Scenario";
@@ -24,99 +28,99 @@ codeunit 9455 "File System Impl."
Initialize(FileAccount);
end;
- internal procedure Initialize(FileAccount: Record "File Account")
+ procedure Initialize(FileAccount: Record "File Account")
begin
CurrFileAccount := FileAccount;
- IFileConnector := FileAccount.Connector;
- Initialized := true;
+ FileSystemConnector := FileAccount.Connector;
+ IsInitialized := true;
end;
- internal procedure ListFiles(Path: Text; FilePaginationData: Codeunit "File Pagination Data"; var FileAccountContent: Record "File Account Content" temporary)
+ procedure ListFiles(Path: Text; FilePaginationData: Codeunit "File Pagination Data"; var FileAccountContent: Record "File Account Content" temporary)
begin
CheckPath(Path);
CheckInitialization();
- IFileConnector.ListFiles(CurrFileAccount."Account Id", Path, FilePaginationData, FileAccountContent);
+ FileSystemConnector.ListFiles(CurrFileAccount."Account Id", Path, FilePaginationData, FileAccountContent);
end;
- internal procedure GetFile(Path: Text; Stream: InStream)
+ procedure GetFile(Path: Text; Stream: InStream)
begin
CheckPath(Path);
CheckInitialization();
- IFileConnector.GetFile(CurrFileAccount."Account Id", Path, Stream);
+ FileSystemConnector.GetFile(CurrFileAccount."Account Id", Path, Stream);
end;
- internal procedure CreateFile(Path: Text; Stream: InStream)
+ procedure CreateFile(Path: Text; Stream: InStream)
begin
CheckPath(Path);
CheckInitialization();
- IFileConnector.CreateFile(CurrFileAccount."Account Id", Path, Stream);
+ FileSystemConnector.CreateFile(CurrFileAccount."Account Id", Path, Stream);
end;
- internal procedure CopyFile(SourcePath: Text; TargetPath: Text)
+ procedure CopyFile(SourcePath: Text; TargetPath: Text)
begin
CheckPath(SourcePath);
CheckPath(TargetPath);
CheckInitialization();
- IFileConnector.CopyFile(CurrFileAccount."Account Id", SourcePath, TargetPath);
+ FileSystemConnector.CopyFile(CurrFileAccount."Account Id", SourcePath, TargetPath);
end;
- internal procedure MoveFile(SourcePath: Text; TargetPath: Text)
+ procedure MoveFile(SourcePath: Text; TargetPath: Text)
begin
CheckPath(SourcePath);
CheckPath(TargetPath);
CheckInitialization();
- IFileConnector.MoveFile(CurrFileAccount."Account Id", SourcePath, TargetPath);
+ FileSystemConnector.MoveFile(CurrFileAccount."Account Id", SourcePath, TargetPath);
end;
- internal procedure FileExists(Path: Text): Boolean
+ procedure FileExists(Path: Text): Boolean
begin
CheckPath(Path);
CheckInitialization();
- exit(IFileConnector.FileExists(CurrFileAccount."Account Id", Path));
+ exit(FileSystemConnector.FileExists(CurrFileAccount."Account Id", Path));
end;
- internal procedure DeleteFile(Path: Text)
+ procedure DeleteFile(Path: Text)
begin
CheckPath(Path);
CheckInitialization();
- IFileConnector.DeleteFile(CurrFileAccount."Account Id", Path);
+ FileSystemConnector.DeleteFile(CurrFileAccount."Account Id", Path);
end;
- internal procedure ListDirectories(Path: Text; FilePaginationData: Codeunit "File Pagination Data"; var FileAccountContent: Record "File Account Content" temporary)
+ procedure ListDirectories(Path: Text; FilePaginationData: Codeunit "File Pagination Data"; var FileAccountContent: Record "File Account Content" temporary)
begin
CheckPath(Path);
CheckInitialization();
- IFileConnector.ListDirectories(CurrFileAccount."Account Id", Path, FilePaginationData, FileAccountContent);
+ FileSystemConnector.ListDirectories(CurrFileAccount."Account Id", Path, FilePaginationData, FileAccountContent);
end;
- internal procedure CreateDirectory(Path: Text)
+ procedure CreateDirectory(Path: Text)
begin
CheckPath(Path);
CheckInitialization();
- IFileConnector.CreateDirectory(CurrFileAccount."Account Id", Path);
+ FileSystemConnector.CreateDirectory(CurrFileAccount."Account Id", Path);
end;
- internal procedure DirectoryExists(Path: Text): Boolean
+ procedure DirectoryExists(Path: Text): Boolean
begin
CheckPath(Path);
CheckInitialization();
- exit(IFileConnector.DirectoryExists(CurrFileAccount."Account Id", Path));
+ exit(FileSystemConnector.DirectoryExists(CurrFileAccount."Account Id", Path));
end;
- internal procedure DeleteDirectory(Path: Text)
+ procedure DeleteDirectory(Path: Text)
begin
CheckPath(Path);
CheckInitialization();
- IFileConnector.DeleteDirectory(CurrFileAccount."Account Id", Path);
+ FileSystemConnector.DeleteDirectory(CurrFileAccount."Account Id", Path);
end;
- internal procedure PathSeparator(): Text
+ procedure PathSeparator(): Text
begin
exit('/');
end;
- internal procedure CombinePath(Path: Text; ChildPath: Text): Text
+ procedure CombinePath(Path: Text; ChildPath: Text): Text
begin
if Path = '' then
exit(ChildPath);
@@ -127,14 +131,14 @@ codeunit 9455 "File System Impl."
exit(Path + ChildPath);
end;
- internal procedure GetParentPath(Path: Text) ParentPath: Text
+ procedure GetParentPath(Path: Text) ParentPath: Text
begin
Path := Path.TrimEnd(PathSeparator());
if Path.TrimEnd(PathSeparator()).Contains(PathSeparator()) then
ParentPath := Path.Substring(1, Path.LastIndexOf(PathSeparator()));
end;
- internal procedure SelectFolderUI(Path: Text; DialogTitle: Text): Text
+ procedure SelectFolderUI(Path: Text; DialogTitle: Text): Text
var
FileAccountContent: Record "File Account Content";
FileAccountBrowser: Page "File Account Browser";
@@ -155,7 +159,7 @@ codeunit 9455 "File System Impl."
exit(CombinePath(FileAccountContent."Parent Directory", FileAccountContent.Name));
end;
- internal procedure SelectFileUI(Path: Text; FileFilter: Text; DialogTitle: Text): Text
+ procedure SelectFileUI(Path: Text; FileFilter: Text; DialogTitle: Text): Text
var
FileAccountContent: Record "File Account Content";
FileAccountBrowser: Page "File Account Browser";
@@ -176,7 +180,7 @@ codeunit 9455 "File System Impl."
exit(CombinePath(FileAccountContent."Parent Directory", FileAccountContent.Name));
end;
- internal procedure SaveFileUI(Path: Text; FileExtension: Text; DialogTitle: Text): Text
+ procedure SaveFileUI(Path: Text; FileExtension: Text; DialogTitle: Text): Text
var
FileAccountContent: Record "File Account Content";
FileAccountBrowser: Page "File Account Browser";
@@ -204,7 +208,7 @@ codeunit 9455 "File System Impl."
exit(CombinePath(FileAccountBrowser.GetCurrentDirectory(), FileNameWithExtenion));
end;
- internal procedure BrowseAccount()
+ procedure BrowseAccount()
var
FileAccountImpl: Codeunit "File Account Impl.";
begin
@@ -216,7 +220,7 @@ codeunit 9455 "File System Impl."
var
NotInitializedErr: Label 'Please call Initalize() first.';
begin
- if Initialized then
+ if IsInitialized then
exit;
Error(NotInitializedErr);
diff --git a/src/System Application/App/File System/src/Lookup/FileAccountBrowser.Page.al b/src/System Application/App/File System/src/Lookup/FileAccountBrowser.Page.al
index 5a14c083a9..a1250f578a 100644
--- a/src/System Application/App/File System/src/Lookup/FileAccountBrowser.Page.al
+++ b/src/System Application/App/File System/src/Lookup/FileAccountBrowser.Page.al
@@ -15,6 +15,8 @@ page 9455 "File Account Browser"
InsertAllowed = false;
DeleteAllowed = false;
Extensible = false;
+ InherentPermissions = X;
+ InherentEntitlements = X;
layout
{
diff --git a/src/System Application/App/File System/src/Lookup/FilePaginationData.Codeunit.al b/src/System Application/App/File System/src/Lookup/FilePaginationData.Codeunit.al
index 3ebdd89743..a12ebbd1fa 100644
--- a/src/System Application/App/File System/src/Lookup/FilePaginationData.Codeunit.al
+++ b/src/System Application/App/File System/src/Lookup/FilePaginationData.Codeunit.al
@@ -7,6 +7,9 @@ namespace System.FileSystem;
codeunit 9456 "File Pagination Data"
{
+ InherentPermissions = X;
+ InherentEntitlements = X;
+
var
Marker: Text;
EndOfListing: Boolean;
diff --git a/src/System Application/App/File System/src/Lookup/FolderNameInput.Page.al b/src/System Application/App/File System/src/Lookup/FolderNameInput.Page.al
index 04db3b7904..1ae4ff3532 100644
--- a/src/System Application/App/File System/src/Lookup/FolderNameInput.Page.al
+++ b/src/System Application/App/File System/src/Lookup/FolderNameInput.Page.al
@@ -11,6 +11,8 @@ page 9456 "Folder Name Input"
Caption = 'Create Folder...';
PageType = StandardDialog;
Extensible = false;
+ InherentPermissions = X;
+ InherentEntitlements = X;
layout
{
diff --git a/src/System Application/App/File System/src/Scenario/FileScenario.Codeunit.al b/src/System Application/App/File System/src/Scenario/FileScenario.Codeunit.al
index 417e3fb945..d76f7df612 100644
--- a/src/System Application/App/File System/src/Scenario/FileScenario.Codeunit.al
+++ b/src/System Application/App/File System/src/Scenario/FileScenario.Codeunit.al
@@ -10,6 +10,9 @@ namespace System.FileSystem;
///
codeunit 9452 "File Scenario"
{
+ InherentPermissions = X;
+ InherentEntitlements = X;
+
///
/// Gets the default file account.
///
diff --git a/src/System Application/App/File System/src/Scenario/FileScenario.Table.al b/src/System Application/App/File System/src/Scenario/FileScenario.Table.al
index 390a295715..723432dfea 100644
--- a/src/System Application/App/File System/src/Scenario/FileScenario.Table.al
+++ b/src/System Application/App/File System/src/Scenario/FileScenario.Table.al
@@ -13,6 +13,8 @@ namespace System.FileSystem;
table 9454 "File Scenario"
{
Access = Internal;
+ InherentPermissions = X;
+ InherentEntitlements = X;
fields
{
diff --git a/src/System Application/App/File System/src/Scenario/FileScenarioSetup.Page.al b/src/System Application/App/File System/src/Scenario/FileScenarioSetup.Page.al
index 22d61e420b..f0c6ff309b 100644
--- a/src/System Application/App/File System/src/Scenario/FileScenarioSetup.Page.al
+++ b/src/System Application/App/File System/src/Scenario/FileScenarioSetup.Page.al
@@ -23,6 +23,8 @@ page 9452 "File Scenario Setup"
ModifyAllowed = false;
SourceTable = "File Account Scenario";
InstructionalText = 'Assign file scenarios';
+ InherentPermissions = X;
+ InherentEntitlements = X;
layout
{
diff --git a/src/System Application/App/File System/src/Scenario/FileScenariosFactBox.Page.al b/src/System Application/App/File System/src/Scenario/FileScenariosFactBox.Page.al
index d803810eec..ede1aaf0fd 100644
--- a/src/System Application/App/File System/src/Scenario/FileScenariosFactBox.Page.al
+++ b/src/System Application/App/File System/src/Scenario/FileScenariosFactBox.Page.al
@@ -21,6 +21,8 @@ page 9453 "File Scenarios FactBox"
ShowFilter = false;
LinksAllowed = false;
Permissions = tabledata "File Scenario" = r;
+ InherentPermissions = X;
+ InherentEntitlements = X;
layout
{
diff --git a/src/System Application/App/File System/src/Scenario/FileScenariosForAccount.Page.al b/src/System Application/App/File System/src/Scenario/FileScenariosForAccount.Page.al
index 1544ade054..47d26285c8 100644
--- a/src/System Application/App/File System/src/Scenario/FileScenariosForAccount.Page.al
+++ b/src/System Application/App/File System/src/Scenario/FileScenariosForAccount.Page.al
@@ -20,6 +20,8 @@ page 9454 "File Scenarios for Account"
Editable = false;
ShowFilter = false;
LinksAllowed = false;
+ InherentPermissions = X;
+ InherentEntitlements = X;
layout
{
From ca7455a7746dcbfc7c033ed2a6e12d811691dcc1 Mon Sep 17 00:00:00 2001
From: Thomas Williamson
Date: Fri, 1 Mar 2024 17:54:40 +0100
Subject: [PATCH 07/43] Add File Pagination Facade
---
.../src/Lookup/FilePaginationData.Codeunit.al | 27 +++++++++++---
.../Lookup/FilePaginationDataImpl.Codeunit.al | 37 +++++++++++++++++++
2 files changed, 58 insertions(+), 6 deletions(-)
create mode 100644 src/System Application/App/File System/src/Lookup/FilePaginationDataImpl.Codeunit.al
diff --git a/src/System Application/App/File System/src/Lookup/FilePaginationData.Codeunit.al b/src/System Application/App/File System/src/Lookup/FilePaginationData.Codeunit.al
index a12ebbd1fa..25637a4c53 100644
--- a/src/System Application/App/File System/src/Lookup/FilePaginationData.Codeunit.al
+++ b/src/System Application/App/File System/src/Lookup/FilePaginationData.Codeunit.al
@@ -11,26 +11,41 @@ codeunit 9456 "File Pagination Data"
InherentEntitlements = X;
var
- Marker: Text;
- EndOfListing: Boolean;
+ FilePaginationDataImpl: Codeunit "File Pagination Data Impl.";
+ ///
+ /// Sets a marker if files and directories can be getted in batches.
+ ///
+ /// Marker value to set.
procedure SetMarker(NewMarker: Text)
begin
- Marker := NewMarker;
+ FilePaginationDataImpl.SetMarker(NewMarker);
end;
+ ///
+ /// Gets the current marker value.
+ ///
+ /// Current marker value.
procedure GetMarker(): Text
begin
- exit(Marker);
+ exit(FilePaginationDataImpl.GetMarker());
end;
+ ///
+ /// Set this value to true, if all files or directoreis have beend read a from the File System.
+ ///
+ /// End of listing reached.
procedure SetEndOfListing(NewEndOfListing: Boolean)
begin
- EndOfListing := NewEndOfListing;
+ FilePaginationDataImpl.SetEndOfListing(NewEndOfListing);
end;
+ ///
+ /// Defines if all batches of directory or file listing has beend received.
+ ///
+ /// End of listing reached.
procedure IsEndOfListing(): Boolean
begin
- exit(EndOfListing);
+ exit(FilePaginationDataImpl.IsEndOfListing());
end;
}
diff --git a/src/System Application/App/File System/src/Lookup/FilePaginationDataImpl.Codeunit.al b/src/System Application/App/File System/src/Lookup/FilePaginationDataImpl.Codeunit.al
new file mode 100644
index 0000000000..857c54dcdb
--- /dev/null
+++ b/src/System Application/App/File System/src/Lookup/FilePaginationDataImpl.Codeunit.al
@@ -0,0 +1,37 @@
+// ------------------------------------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License. See License.txt in the project root for license information.
+// ------------------------------------------------------------------------------------------------
+
+namespace System.FileSystem;
+
+codeunit 9457 "File Pagination Data Impl."
+{
+ Access = Internal;
+ InherentPermissions = X;
+ InherentEntitlements = X;
+
+ var
+ Marker: Text;
+ EndOfListing: Boolean;
+
+ procedure SetMarker(NewMarker: Text)
+ begin
+ Marker := NewMarker;
+ end;
+
+ procedure GetMarker(): Text
+ begin
+ exit(Marker);
+ end;
+
+ procedure SetEndOfListing(NewEndOfListing: Boolean)
+ begin
+ EndOfListing := NewEndOfListing;
+ end;
+
+ procedure IsEndOfListing(): Boolean
+ begin
+ exit(EndOfListing);
+ end;
+}
From ae719ddd11313a1ca1f2506908cf006ec0f499b5 Mon Sep 17 00:00:00 2001
From: Thomas Williamson
Date: Fri, 1 Mar 2024 18:41:18 +0100
Subject: [PATCH 08/43] Reduce code in file browser page
---
.../src/Account/FileAccountImpl.Codeunit.al | 2 +-
.../src/FileSystem/FileSystemImp.Codeunit.al | 6 +-
.../src/Lookup/FileAccountBrowser.Page.al | 125 ++----------------
.../Lookup/FileAccountBrowserMgt.Codeunit.al | 125 ++++++++++++++++++
4 files changed, 140 insertions(+), 118 deletions(-)
create mode 100644 src/System Application/App/File System/src/Lookup/FileAccountBrowserMgt.Codeunit.al
diff --git a/src/System Application/App/File System/src/Account/FileAccountImpl.Codeunit.al b/src/System Application/App/File System/src/Account/FileAccountImpl.Codeunit.al
index 58768ea4dd..4568e3b9ab 100644
--- a/src/System Application/App/File System/src/Account/FileAccountImpl.Codeunit.al
+++ b/src/System Application/App/File System/src/Account/FileAccountImpl.Codeunit.al
@@ -210,7 +210,7 @@ codeunit 9451 "File Account Impl."
if IsNullGuid(FileAccount."Account Id") then
exit;
- FileAccountBrowser.SetFileAcconut(FileAccount);
+ FileAccountBrowser.SetFileAccount(FileAccount);
FileAccountBrowser.BrowseFileAccount('');
FileAccountBrowser.Run();
end;
diff --git a/src/System Application/App/File System/src/FileSystem/FileSystemImp.Codeunit.al b/src/System Application/App/File System/src/FileSystem/FileSystemImp.Codeunit.al
index 020dbf7a57..6b4fadcfc2 100644
--- a/src/System Application/App/File System/src/FileSystem/FileSystemImp.Codeunit.al
+++ b/src/System Application/App/File System/src/FileSystem/FileSystemImp.Codeunit.al
@@ -147,7 +147,7 @@ codeunit 9455 "File System Impl."
CheckInitialization();
FileAccountBrowser.SetPageCaption(DialogTitle);
- FileAccountBrowser.SetFileAcconut(CurrFileAccount);
+ FileAccountBrowser.SetFileAccount(CurrFileAccount);
FileAccountBrowser.EnableDirectoryLookupMode(Path);
if FileAccountBrowser.RunModal() <> Action::LookupOK then
exit('');
@@ -168,7 +168,7 @@ codeunit 9455 "File System Impl."
CheckInitialization();
FileAccountBrowser.SetPageCaption(DialogTitle);
- FileAccountBrowser.SetFileAcconut(CurrFileAccount);
+ FileAccountBrowser.SetFileAccount(CurrFileAccount);
FileAccountBrowser.EnableFileLookupMode(Path, FileFilter);
if FileAccountBrowser.RunModal() <> Action::LookupOK then
exit('');
@@ -195,7 +195,7 @@ codeunit 9455 "File System Impl."
Error(PleaseProvideFileExtensionErr);
FileAccountBrowser.SetPageCaption(DialogTitle);
- FileAccountBrowser.SetFileAcconut(CurrFileAccount);
+ FileAccountBrowser.SetFileAccount(CurrFileAccount);
FileAccountBrowser.EnableSaveFileLookupMode(Path, FileExtension);
if FileAccountBrowser.RunModal() <> Action::LookupOK then
exit('');
diff --git a/src/System Application/App/File System/src/Lookup/FileAccountBrowser.Page.al b/src/System Application/App/File System/src/Lookup/FileAccountBrowser.Page.al
index a1250f578a..455c81bce4 100644
--- a/src/System Application/App/File System/src/Lookup/FileAccountBrowser.Page.al
+++ b/src/System Application/App/File System/src/Lookup/FileAccountBrowser.Page.al
@@ -43,7 +43,7 @@ page 9455 "File Account Browser"
(Rec.Type = Rec.Type::Directory):
BrowseFolder(Rec);
(not IsInLookupMode):
- DownloadFile(Rec);
+ FileAccountBrowserMgt.DownloadFile(Rec);
end;
end;
}
@@ -87,7 +87,7 @@ page 9455 "File Account Browser"
trigger OnAction()
begin
- UploadFile();
+ FileAccountBrowserMgt.UploadFile(CurrPath);
BrowseFolder(CurrPath);
end;
}
@@ -101,7 +101,7 @@ page 9455 "File Account Browser"
trigger OnAction()
begin
- CreateDirectory();
+ FileAccountBrowserMgt.CreateDirectory(CurrPath);
BrowseFolder(CurrPath);
end;
}
@@ -115,7 +115,7 @@ page 9455 "File Account Browser"
trigger OnAction()
begin
- DeleteFileOrDirectory();
+ FileAccountBrowserMgt.DeleteFileOrDirectory(Rec);
BrowseFolder(CurrPath);
end;
}
@@ -123,9 +123,9 @@ page 9455 "File Account Browser"
}
var
- FileSystem: Codeunit "File System";
+ FileAccountBrowserMgt: Codeunit "File Account Browser Mgt.";
CurrPath, CurrFileFilter, SaveFileName, CurrPageCaption : Text;
- ParentFolderExists, DoNotLoadFields, IsInLookupMode, ShowFileName : Boolean;
+ DoNotLoadFiles, IsInLookupMode, ShowFileName : Boolean;
trigger OnOpenPage()
begin
@@ -133,9 +133,9 @@ page 9455 "File Account Browser"
CurrPage.Caption(CurrPageCaption);
end;
- internal procedure SetFileAcconut(FileAccount: Record "File Account")
+ internal procedure SetFileAccount(FileAccount: Record "File Account")
begin
- FileSystem.Initialize(FileAccount);
+ FileAccountBrowserMgt.SetFileAccount(FileAccount);
end;
internal procedure BrowseFileAccount(Path: Text)
@@ -152,7 +152,7 @@ page 9455 "File Account Browser"
internal procedure EnableDirectoryLookupMode(Path: Text)
begin
- DoNotLoadFields := true;
+ DoNotLoadFiles := true;
EnableLookupMode();
BrowseFolder(Path);
end;
@@ -177,20 +177,11 @@ page 9455 "File Account Browser"
exit(SaveFileName);
end;
-
internal procedure SetPageCaption(NewCaption: Text)
begin
CurrPageCaption := NewCaption;
end;
- local procedure StripNotsupportChrInFileName(InText: Text): Text
- var
- InvalidChrStringTxt: Label '"#%&*:<>?\/{|}~', Locked = true;
- begin
- InText := DelChr(InText, '=', InvalidChrStringTxt);
- exit(InText);
- end;
-
local procedure EnableLookupMode()
begin
IsInLookupMode := true;
@@ -201,106 +192,12 @@ page 9455 "File Account Browser"
var
Path: Text;
begin
- Path := FileSystem.CombinePath(TempFileAccountContent."Parent Directory", TempFileAccountContent.Name);
+ Path := FileAccountBrowserMgt.CombinePath(TempFileAccountContent."Parent Directory", TempFileAccountContent.Name);
BrowseFolder(Path);
end;
local procedure BrowseFolder(Path: Text)
- var
- FilePaginationData: Codeunit "File Pagination Data";
- begin
- CurrPath := Path.TrimEnd('/');
- ParentFolderExists := Path <> '';
- Rec.DeleteAll();
-
- repeat
- FileSystem.ListDirectories(Path, FilePaginationData, Rec);
- until FilePaginationData.IsEndOfListing();
-
- ListFiles(Path);
- if Rec.FindFirst() then;
- end;
-
- local procedure DownloadFile(var TempFileAccountContent: Record "File Account Content" temporary)
- var
- Stream: InStream;
- begin
- FileSystem.GetFile(FileSystem.CombinePath(TempFileAccountContent."Parent Directory", TempFileAccountContent.Name), Stream);
- DownloadFromStream(Stream, '', '', '', TempFileAccountContent.Name);
- end;
-
- local procedure UploadFile()
- var
- UploadDialogTxt: Label 'Upload File';
- FromFile: Text;
- Stream: InStream;
- begin
- if not UploadIntoStream(UploadDialogTxt, '', '', FromFile, Stream) then
- exit;
-
- FileSystem.CreateFile(FileSystem.CombinePath(CurrPath, FromFile), Stream);
- end;
-
- local procedure CreateDirectory()
- var
- FolderNameInput: Page "Folder Name Input";
- FolderName: Text;
- begin
- if FolderNameInput.RunModal() <> Action::OK then
- exit;
-
- FolderName := StripNotsupportChrInFileName(FolderNameInput.GetFolderName());
- FileSystem.CreateDirectory(FileSystem.CombinePath(CurrPath, FolderName));
- end;
-
- local procedure ListFiles(var Path: Text)
- var
- FileAccountContent: Record "File Account Content" temporary;
- FilePaginationData: Codeunit "File Pagination Data";
begin
- if DoNotLoadFields then
- exit;
-
- repeat
- FileSystem.ListFiles(Path, FilePaginationData, FileAccountContent);
- until FilePaginationData.IsEndOfListing();
-
- AddFiles(FileAccountContent);
- end;
-
- local procedure AddFiles(var FileAccountContent: Record "File Account Content" temporary)
- begin
- if CurrFileFilter <> '' then
- FileAccountContent.SetFilter(Name, CurrFileFilter);
-
- if FileAccountContent.FindSet() then
- repeat
- Rec.Init();
- Rec.TransferFields(FileAccountContent);
- Rec.Insert();
- until FileAccountContent.Next() = 0;
-
- Rec.Init();
- Rec.Name := '..';
- Rec.Type := Rec.Type::Directory;
- Rec."Parent Directory" := FileSystem.GetParentPath(CurrPath);
- Rec.Insert();
- end;
-
- local procedure DeleteFileOrDirectory()
- var
- PathToDelete: Text;
- DeleteQst: Label 'Delete %1?', Comment = '%1 - Path to Delete';
- begin
- PathToDelete := FileSystem.CombinePath(Rec."Parent Directory", Rec.Name);
- if not Confirm(DeleteQst, false, PathToDelete) then
- exit;
-
- case Rec.Type of
- Rec.Type::Directory:
- FileSystem.DeleteDirectory(PathToDelete);
- Rec.Type::File:
- FileSystem.DeleteFile(PathToDelete);
- end;
+ FileAccountBrowserMgt.BrowseFolder(Rec, Path, CurrPath, DoNotLoadFiles, CurrFileFilter);
end;
}
diff --git a/src/System Application/App/File System/src/Lookup/FileAccountBrowserMgt.Codeunit.al b/src/System Application/App/File System/src/Lookup/FileAccountBrowserMgt.Codeunit.al
new file mode 100644
index 0000000000..f28c824f65
--- /dev/null
+++ b/src/System Application/App/File System/src/Lookup/FileAccountBrowserMgt.Codeunit.al
@@ -0,0 +1,125 @@
+codeunit 9458 "File Account Browser Mgt."
+{
+ Access = Internal;
+ InherentPermissions = X;
+ InherentEntitlements = X;
+
+ var
+ FileSystem: Codeunit "File System";
+
+ procedure SetFileAccount(FileAccount: Record "File Account")
+ begin
+ FileSystem.Initialize(FileAccount);
+ end;
+
+ procedure StripNotsupportChrInFileName(InText: Text): Text
+ var
+ InvalidChrStringTxt: Label '"#%&*:<>?\/{|}~', Locked = true;
+ begin
+ InText := DelChr(InText, '=', InvalidChrStringTxt);
+ exit(InText);
+ end;
+
+ procedure BrowseFolder(var TempFileAccountContent: Record "File Account Content" temporary; Path: Text; var CurrPath: Text; DoNotLoadFiles: Boolean; FileNameFilter: Text)
+ var
+ FilePaginationData: Codeunit "File Pagination Data";
+ begin
+ CurrPath := Path.TrimEnd('/');
+ TempFileAccountContent.DeleteAll();
+
+ repeat
+ FileSystem.ListDirectories(Path, FilePaginationData, TempFileAccountContent);
+ until FilePaginationData.IsEndOfListing();
+
+ ListFiles(TempFileAccountContent, Path, DoNotLoadFiles, CurrPath, FileNameFilter);
+ if TempFileAccountContent.FindFirst() then;
+ end;
+
+ procedure DownloadFile(var TempFileAccountContent: Record "File Account Content" temporary)
+ var
+ Stream: InStream;
+ begin
+ FileSystem.GetFile(FileSystem.CombinePath(TempFileAccountContent."Parent Directory", TempFileAccountContent.Name), Stream);
+ DownloadFromStream(Stream, '', '', '', TempFileAccountContent.Name);
+ end;
+
+ procedure UploadFile(Path: Text)
+ var
+ UploadDialogTxt: Label 'Upload File';
+ FromFile: Text;
+ Stream: InStream;
+ begin
+ if not UploadIntoStream(UploadDialogTxt, '', '', FromFile, Stream) then
+ exit;
+
+ FileSystem.CreateFile(FileSystem.CombinePath(Path, FromFile), Stream);
+ end;
+
+ procedure CreateDirectory(Path: Text)
+ var
+ FolderNameInput: Page "Folder Name Input";
+ FolderName: Text;
+ begin
+ if FolderNameInput.RunModal() <> Action::OK then
+ exit;
+
+ FolderName := StripNotsupportChrInFileName(FolderNameInput.GetFolderName());
+ FileSystem.CreateDirectory(FileSystem.CombinePath(Path, FolderName));
+ end;
+
+ local procedure ListFiles(var FileAccountContent: Record "File Account Content" temporary; var Path: Text; DoNotLoadFields: Boolean; CurrPath: Text; FileNameFilter: Text)
+ var
+ FileAccountContentToAdd: Record "File Account Content" temporary;
+ FilePaginationData: Codeunit "File Pagination Data";
+ begin
+ if DoNotLoadFields then
+ exit;
+
+ repeat
+ FileSystem.ListFiles(Path, FilePaginationData, FileAccountContent);
+ until FilePaginationData.IsEndOfListing();
+
+ AddFiles(FileAccountContent, FileAccountContentToAdd, CurrPath, FileNameFilter);
+ end;
+
+ local procedure AddFiles(var FileAccountContent: Record "File Account Content" temporary; var FileAccountContentToAdd: Record "File Account Content" temporary; CurrPath: Text; FileNameFilter: Text)
+ begin
+ if FileNameFilter <> '' then
+ FileAccountContentToAdd.SetFilter(Name, FileNameFilter);
+
+ if FileAccountContentToAdd.FindSet() then
+ repeat
+ FileAccountContent.Init();
+ FileAccountContent.TransferFields(FileAccountContentToAdd);
+ FileAccountContent.Insert();
+ until FileAccountContentToAdd.Next() = 0;
+
+ FileAccountContent.Init();
+ FileAccountContent.Name := '..';
+ FileAccountContent.Type := FileAccountContent.Type::Directory;
+ FileAccountContent."Parent Directory" := FileSystem.GetParentPath(CurrPath);
+ FileAccountContent.Insert();
+ end;
+
+ procedure DeleteFileOrDirectory(var TempFileAccountContent: Record "File Account Content" temporary)
+ var
+ PathToDelete: Text;
+ DeleteQst: Label 'Delete %1?', Comment = '%1 - Path to Delete';
+ begin
+ PathToDelete := FileSystem.CombinePath(TempFileAccountContent."Parent Directory", TempFileAccountContent.Name);
+ if not Confirm(DeleteQst, false, PathToDelete) then
+ exit;
+
+ case TempFileAccountContent.Type of
+ TempFileAccountContent.Type::Directory:
+ FileSystem.DeleteDirectory(PathToDelete);
+ TempFileAccountContent.Type::File:
+ FileSystem.DeleteFile(PathToDelete);
+ end;
+ end;
+
+ internal procedure CombinePath(Path: Text; ChildPath: Text): Text
+ begin
+ exit(FileSystem.CombinePath(Path, ChildPath));
+ end;
+}
\ No newline at end of file
From 8d8eee9244197a15b6ec050eab93c7d74c3cefed Mon Sep 17 00:00:00 2001
From: Thomas Williamson
Date: Fri, 1 Mar 2024 21:22:28 +0100
Subject: [PATCH 09/43] Use only test lib for internal access
---
.../App/File System/app.json | 5 ----
.../src/FileSystemTestLib.Codeunit.al | 25 +++++++++++++++++++
.../src/{ => Mock}/ConnectorMock.Codeunit.al | 0
.../FileAccountsSelectionMock.Codeunit.al | 5 ++--
.../{ => Mock}/FileScenarioMock.Codeunit.al | 0
.../src/FileScenarioTest.Codeunit.al | 17 +++++++------
6 files changed, 36 insertions(+), 16 deletions(-)
create mode 100644 src/System Application/Test Library/File System/src/FileSystemTestLib.Codeunit.al
rename src/System Application/Test Library/File System/src/{ => Mock}/ConnectorMock.Codeunit.al (100%)
rename src/System Application/{Test/File System/src/Mocks => Test Library/File System/src/Mock}/FileAccountsSelectionMock.Codeunit.al (91%)
rename src/System Application/Test Library/File System/src/{ => Mock}/FileScenarioMock.Codeunit.al (100%)
diff --git a/src/System Application/App/File System/app.json b/src/System Application/App/File System/app.json
index d88cfd431f..8454264f45 100644
--- a/src/System Application/App/File System/app.json
+++ b/src/System Application/App/File System/app.json
@@ -49,11 +49,6 @@
}
],
"internalsVisibleTo": [
- {
- "id": "fff6eee5-083f-4f07-9a49-e34f7e2aad77",
- "name": "File Systen Test",
- "publisher": "Microsoft"
- },
{
"id": "f188754b-3ffb-443a-9507-f5fbdae3af2c",
"name": "File System Test Library",
diff --git a/src/System Application/Test Library/File System/src/FileSystemTestLib.Codeunit.al b/src/System Application/Test Library/File System/src/FileSystemTestLib.Codeunit.al
new file mode 100644
index 0000000000..f168e94716
--- /dev/null
+++ b/src/System Application/Test Library/File System/src/FileSystemTestLib.Codeunit.al
@@ -0,0 +1,25 @@
+// ------------------------------------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License. See License.txt in the project root for license information.
+// ------------------------------------------------------------------------------------------------
+
+namespace System.TestLibraries.FileSystem;
+
+using System.FileSystem;
+
+codeunit 80204 "File System Test Lib."
+{
+ Permissions = tabledata "File Scenario" = rid;
+
+ procedure GetFileScenarioAccountIdAndFileConnector(Scenario: Enum "File Scenario"; var AccountId: Guid; var FileSystemConnector: Interface "File System Connector"): Boolean
+ var
+ FileScenarios: Record "File Scenario";
+ begin
+ if not FileScenarios.Get(Scenario) then
+ exit;
+
+ AccountId := FileScenarios."Account Id";
+ FileSystemConnector := FileScenarios.Connector;
+ exit(true);
+ end;
+}
\ No newline at end of file
diff --git a/src/System Application/Test Library/File System/src/ConnectorMock.Codeunit.al b/src/System Application/Test Library/File System/src/Mock/ConnectorMock.Codeunit.al
similarity index 100%
rename from src/System Application/Test Library/File System/src/ConnectorMock.Codeunit.al
rename to src/System Application/Test Library/File System/src/Mock/ConnectorMock.Codeunit.al
diff --git a/src/System Application/Test/File System/src/Mocks/FileAccountsSelectionMock.Codeunit.al b/src/System Application/Test Library/File System/src/Mock/FileAccountsSelectionMock.Codeunit.al
similarity index 91%
rename from src/System Application/Test/File System/src/Mocks/FileAccountsSelectionMock.Codeunit.al
rename to src/System Application/Test Library/File System/src/Mock/FileAccountsSelectionMock.Codeunit.al
index 111bc19247..c57df451a9 100644
--- a/src/System Application/Test/File System/src/Mocks/FileAccountsSelectionMock.Codeunit.al
+++ b/src/System Application/Test Library/File System/src/Mock/FileAccountsSelectionMock.Codeunit.al
@@ -10,15 +10,14 @@ using System.FileSystem;
///
/// Used to mock selected file accounts on File Accounts page.
///
-codeunit 134697 "File System Acc Selection Mock"
+codeunit 80203 "File System Acc Selection Mock"
{
- Access = Internal;
EventSubscriberInstance = Manual;
var
SelectionFilterLbl: Label '%1|%2', Locked = true;
- internal procedure SelectAccount(AccountId: Guid)
+ procedure SelectAccount(AccountId: Guid)
begin
SelectedAccounts.Add(AccountId);
end;
diff --git a/src/System Application/Test Library/File System/src/FileScenarioMock.Codeunit.al b/src/System Application/Test Library/File System/src/Mock/FileScenarioMock.Codeunit.al
similarity index 100%
rename from src/System Application/Test Library/File System/src/FileScenarioMock.Codeunit.al
rename to src/System Application/Test Library/File System/src/Mock/FileScenarioMock.Codeunit.al
diff --git a/src/System Application/Test/File System/src/FileScenarioTest.Codeunit.al b/src/System Application/Test/File System/src/FileScenarioTest.Codeunit.al
index e53571ef71..8435cee09f 100644
--- a/src/System Application/Test/File System/src/FileScenarioTest.Codeunit.al
+++ b/src/System Application/Test/File System/src/FileScenarioTest.Codeunit.al
@@ -13,7 +13,6 @@ using System.TestLibraries.Security.AccessControl;
codeunit 134693 "File Scenario Test"
{
Subtype = Test;
- Permissions = tabledata "File Scenario" = r;
var
Assert: Codeunit "Library Assert";
@@ -216,7 +215,9 @@ codeunit 134693 "File Scenario Test"
var
FileAccount: Record "File Account";
AnotherAccount: Record "File Account";
- FileScenarios: Record "File Scenario";
+ FileSystemTestLib: Codeunit "File System Test Lib.";
+ FileSystemConnector: Interface "File System Connector";
+ AccountId: Guid;
Scenario: Enum "File Scenario";
begin
// [Scenario] When SetAccount is called, the entry in the database is as expected
@@ -232,9 +233,9 @@ codeunit 134693 "File Scenario Test"
FileScenario.SetFileAccount(Scenario, FileAccount);
// [Then] The scenario exists and is as expected
- Assert.IsTrue(FileScenarios.Get(Scenario), 'The File scenario should exist');
- Assert.AreEqual(FileScenarios."Account Id", FileAccount."Account Id", 'Wrong accound ID');
- Assert.AreEqual(FileScenarios.Connector, FileAccount.Connector, 'Wrong connector');
+ Assert.IsTrue(FileSystemTestLib.GetFileScenarioAccountIdAndFileConnector(Scenario, AccountId, FileSystemConnector), 'The File scenario should exist');
+ Assert.AreEqual(AccountId, FileAccount."Account Id", 'Wrong accound ID');
+ Assert.AreEqual(FileSystemConnector, FileAccount.Connector, 'Wrong connector');
AnotherAccount."Account Id" := Any.GuidValue();
AnotherAccount.Connector := Enum::"File System Connector"::"Test File System Connector";
@@ -243,9 +244,9 @@ codeunit 134693 "File Scenario Test"
FileScenario.SetFileAccount(Scenario, AnotherAccount);
// [Then] The scenario still exists and is as expected
- Assert.IsTrue(FileScenarios.Get(Scenario), 'The File scenario should exist');
- Assert.AreEqual(FileScenarios."Account Id", AnotherAccount."Account Id", 'Wrong accound ID');
- Assert.AreEqual(FileScenarios.Connector, AnotherAccount.Connector, 'Wrong connector');
+ Assert.IsTrue(FileSystemTestLib.GetFileScenarioAccountIdAndFileConnector(Scenario, AccountId, FileSystemConnector), 'The File scenario should exist');
+ Assert.AreEqual(AccountId, AnotherAccount."Account Id", 'Wrong accound ID');
+ Assert.AreEqual(FileSystemConnector, AnotherAccount.Connector, 'Wrong connector');
end;
[Test]
From 4258a0b72f690d14c1957ce4cf9758e78b6b38a9 Mon Sep 17 00:00:00 2001
From: Thomas Williamson
Date: Fri, 1 Mar 2024 21:24:38 +0100
Subject: [PATCH 10/43] Fix variable names
---
.../src/Lookup/FileAccountBrowser.Page.al | 30 +++++++++----------
.../Lookup/FileAccountBrowserMgt.Codeunit.al | 14 ++++-----
2 files changed, 22 insertions(+), 22 deletions(-)
diff --git a/src/System Application/App/File System/src/Lookup/FileAccountBrowser.Page.al b/src/System Application/App/File System/src/Lookup/FileAccountBrowser.Page.al
index 455c81bce4..4a91904d20 100644
--- a/src/System Application/App/File System/src/Lookup/FileAccountBrowser.Page.al
+++ b/src/System Application/App/File System/src/Lookup/FileAccountBrowser.Page.al
@@ -22,7 +22,7 @@ page 9455 "File Account Browser"
{
area(content)
{
- field(CurrPathField; CurrPath)
+ field(CurrentPathField; CurrentPath)
{
Caption = 'Path';
ShowCaption = false;
@@ -87,8 +87,8 @@ page 9455 "File Account Browser"
trigger OnAction()
begin
- FileAccountBrowserMgt.UploadFile(CurrPath);
- BrowseFolder(CurrPath);
+ FileAccountBrowserMgt.UploadFile(CurrentPath);
+ BrowseFolder(CurrentPath);
end;
}
action("Create Directory")
@@ -101,8 +101,8 @@ page 9455 "File Account Browser"
trigger OnAction()
begin
- FileAccountBrowserMgt.CreateDirectory(CurrPath);
- BrowseFolder(CurrPath);
+ FileAccountBrowserMgt.CreateDirectory(CurrentPath);
+ BrowseFolder(CurrentPath);
end;
}
action(Delete)
@@ -116,7 +116,7 @@ page 9455 "File Account Browser"
trigger OnAction()
begin
FileAccountBrowserMgt.DeleteFileOrDirectory(Rec);
- BrowseFolder(CurrPath);
+ BrowseFolder(CurrentPath);
end;
}
}
@@ -124,13 +124,13 @@ page 9455 "File Account Browser"
var
FileAccountBrowserMgt: Codeunit "File Account Browser Mgt.";
- CurrPath, CurrFileFilter, SaveFileName, CurrPageCaption : Text;
+ CurrentPath, FileFilter, SaveFileName, CurrentPageCaption : Text;
DoNotLoadFiles, IsInLookupMode, ShowFileName : Boolean;
trigger OnOpenPage()
begin
- if CurrPageCaption <> '' then
- CurrPage.Caption(CurrPageCaption);
+ if CurrentPageCaption <> '' then
+ CurrPage.Caption(CurrentPageCaption);
end;
internal procedure SetFileAccount(FileAccount: Record "File Account")
@@ -143,9 +143,9 @@ page 9455 "File Account Browser"
BrowseFolder('');
end;
- internal procedure EnableFileLookupMode(Path: Text; FileFilter: Text)
+ internal procedure EnableFileLookupMode(Path: Text; PassedFileFilter: Text)
begin
- CurrFileFilter := FileFilter;
+ FileFilter := PassedFileFilter;
EnableLookupMode();
BrowseFolder(Path);
end;
@@ -162,14 +162,14 @@ page 9455 "File Account Browser"
FileFilterTok: Label '*.%1', Locked = true;
begin
ShowFileName := true;
- CurrFileFilter := StrSubstNo(FileFilterTok, FileExtension);
+ FileFilter := StrSubstNo(FileFilterTok, FileExtension);
EnableLookupMode();
BrowseFolder(Path);
end;
internal procedure GetCurrentDirectory(): Text
begin
- exit(CurrPath);
+ exit(CurrentPath);
end;
internal procedure GetFileName(): Text
@@ -179,7 +179,7 @@ page 9455 "File Account Browser"
internal procedure SetPageCaption(NewCaption: Text)
begin
- CurrPageCaption := NewCaption;
+ CurrentPageCaption := NewCaption;
end;
local procedure EnableLookupMode()
@@ -198,6 +198,6 @@ page 9455 "File Account Browser"
local procedure BrowseFolder(Path: Text)
begin
- FileAccountBrowserMgt.BrowseFolder(Rec, Path, CurrPath, DoNotLoadFiles, CurrFileFilter);
+ FileAccountBrowserMgt.BrowseFolder(Rec, Path, CurrentPath, DoNotLoadFiles, FileFilter);
end;
}
diff --git a/src/System Application/App/File System/src/Lookup/FileAccountBrowserMgt.Codeunit.al b/src/System Application/App/File System/src/Lookup/FileAccountBrowserMgt.Codeunit.al
index f28c824f65..5d824547cd 100644
--- a/src/System Application/App/File System/src/Lookup/FileAccountBrowserMgt.Codeunit.al
+++ b/src/System Application/App/File System/src/Lookup/FileAccountBrowserMgt.Codeunit.al
@@ -20,18 +20,18 @@ codeunit 9458 "File Account Browser Mgt."
exit(InText);
end;
- procedure BrowseFolder(var TempFileAccountContent: Record "File Account Content" temporary; Path: Text; var CurrPath: Text; DoNotLoadFiles: Boolean; FileNameFilter: Text)
+ procedure BrowseFolder(var TempFileAccountContent: Record "File Account Content" temporary; Path: Text; var CurrentPath: Text; DoNotLoadFiles: Boolean; FileNameFilter: Text)
var
FilePaginationData: Codeunit "File Pagination Data";
begin
- CurrPath := Path.TrimEnd('/');
+ CurrentPath := Path.TrimEnd('/');
TempFileAccountContent.DeleteAll();
repeat
FileSystem.ListDirectories(Path, FilePaginationData, TempFileAccountContent);
until FilePaginationData.IsEndOfListing();
- ListFiles(TempFileAccountContent, Path, DoNotLoadFiles, CurrPath, FileNameFilter);
+ ListFiles(TempFileAccountContent, Path, DoNotLoadFiles, CurrentPath, FileNameFilter);
if TempFileAccountContent.FindFirst() then;
end;
@@ -67,7 +67,7 @@ codeunit 9458 "File Account Browser Mgt."
FileSystem.CreateDirectory(FileSystem.CombinePath(Path, FolderName));
end;
- local procedure ListFiles(var FileAccountContent: Record "File Account Content" temporary; var Path: Text; DoNotLoadFields: Boolean; CurrPath: Text; FileNameFilter: Text)
+ local procedure ListFiles(var FileAccountContent: Record "File Account Content" temporary; var Path: Text; DoNotLoadFields: Boolean; CurrentPath: Text; FileNameFilter: Text)
var
FileAccountContentToAdd: Record "File Account Content" temporary;
FilePaginationData: Codeunit "File Pagination Data";
@@ -79,10 +79,10 @@ codeunit 9458 "File Account Browser Mgt."
FileSystem.ListFiles(Path, FilePaginationData, FileAccountContent);
until FilePaginationData.IsEndOfListing();
- AddFiles(FileAccountContent, FileAccountContentToAdd, CurrPath, FileNameFilter);
+ AddFiles(FileAccountContent, FileAccountContentToAdd, CurrentPath, FileNameFilter);
end;
- local procedure AddFiles(var FileAccountContent: Record "File Account Content" temporary; var FileAccountContentToAdd: Record "File Account Content" temporary; CurrPath: Text; FileNameFilter: Text)
+ local procedure AddFiles(var FileAccountContent: Record "File Account Content" temporary; var FileAccountContentToAdd: Record "File Account Content" temporary; CurrentPath: Text; FileNameFilter: Text)
begin
if FileNameFilter <> '' then
FileAccountContentToAdd.SetFilter(Name, FileNameFilter);
@@ -97,7 +97,7 @@ codeunit 9458 "File Account Browser Mgt."
FileAccountContent.Init();
FileAccountContent.Name := '..';
FileAccountContent.Type := FileAccountContent.Type::Directory;
- FileAccountContent."Parent Directory" := FileSystem.GetParentPath(CurrPath);
+ FileAccountContent."Parent Directory" := FileSystem.GetParentPath(CurrentPath);
FileAccountContent.Insert();
end;
From 30a0622b0491c084c32ad1b991249385879ac5cb Mon Sep 17 00:00:00 2001
From: Thomas Williamson
Date: Wed, 10 Apr 2024 09:52:10 +0200
Subject: [PATCH 11/43] Add review suggestions
---
.../src/Lookup/FileAccountBrowserMgt.Codeunit.al | 7 +++++++
.../App/File System/src/Lookup/FileType.Enum.al | 4 ++--
2 files changed, 9 insertions(+), 2 deletions(-)
diff --git a/src/System Application/App/File System/src/Lookup/FileAccountBrowserMgt.Codeunit.al b/src/System Application/App/File System/src/Lookup/FileAccountBrowserMgt.Codeunit.al
index 5d824547cd..4f1652ffae 100644
--- a/src/System Application/App/File System/src/Lookup/FileAccountBrowserMgt.Codeunit.al
+++ b/src/System Application/App/File System/src/Lookup/FileAccountBrowserMgt.Codeunit.al
@@ -1,3 +1,10 @@
+// ------------------------------------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License. See License.txt in the project root for license information.
+// ------------------------------------------------------------------------------------------------
+
+namespace System.FileSystem;
+
codeunit 9458 "File Account Browser Mgt."
{
Access = Internal;
diff --git a/src/System Application/App/File System/src/Lookup/FileType.Enum.al b/src/System Application/App/File System/src/Lookup/FileType.Enum.al
index 4f707a962a..7e814d99bf 100644
--- a/src/System Application/App/File System/src/Lookup/FileType.Enum.al
+++ b/src/System Application/App/File System/src/Lookup/FileType.Enum.al
@@ -18,7 +18,7 @@ enum 9452 "File Type"
///
value(0; Directory)
{
- Caption = 'Directory', Locked = true;
+ Caption = 'Directory';
}
///
@@ -26,6 +26,6 @@ enum 9452 "File Type"
///
value(1; File)
{
- Caption = 'File', Locked = true;
+ Caption = 'File';
}
}
\ No newline at end of file
From 5b3228ab144ac8ac1277fa7c1a0ae1b7bff3380d Mon Sep 17 00:00:00 2001
From: Thomas Williamson
Date: Wed, 10 Apr 2024 11:07:25 +0200
Subject: [PATCH 12/43] Solve name and id conflicts
---
.../FileAccountsSelectionMock.Codeunit.al | 2 +-
...eunit.al => FileConnectorMock.Codeunit.al} | 2 +-
.../src/Mock/FileScenarioMock.Codeunit.al | 2 +-
.../src/TestFileSystemConnector.Codeunit.al | 8 +-
.../src/FileAccountsTest.Codeunit.al | 102 +++++++++---------
.../src/FileScenarioPageTest.Codeunit.al | 24 ++---
.../src/FileScenarioTest.Codeunit.al | 20 ++--
7 files changed, 80 insertions(+), 80 deletions(-)
rename src/System Application/Test Library/File System/src/Mock/{ConnectorMock.Codeunit.al => FileConnectorMock.Codeunit.al} (99%)
diff --git a/src/System Application/Test Library/File System/src/Mock/FileAccountsSelectionMock.Codeunit.al b/src/System Application/Test Library/File System/src/Mock/FileAccountsSelectionMock.Codeunit.al
index c57df451a9..847045e11a 100644
--- a/src/System Application/Test Library/File System/src/Mock/FileAccountsSelectionMock.Codeunit.al
+++ b/src/System Application/Test Library/File System/src/Mock/FileAccountsSelectionMock.Codeunit.al
@@ -10,7 +10,7 @@ using System.FileSystem;
///
/// Used to mock selected file accounts on File Accounts page.
///
-codeunit 80203 "File System Acc Selection Mock"
+codeunit 134762 "File System Acc Selection Mock"
{
EventSubscriberInstance = Manual;
diff --git a/src/System Application/Test Library/File System/src/Mock/ConnectorMock.Codeunit.al b/src/System Application/Test Library/File System/src/Mock/FileConnectorMock.Codeunit.al
similarity index 99%
rename from src/System Application/Test Library/File System/src/Mock/ConnectorMock.Codeunit.al
rename to src/System Application/Test Library/File System/src/Mock/FileConnectorMock.Codeunit.al
index 79885c532c..fcba1bb905 100644
--- a/src/System Application/Test Library/File System/src/Mock/ConnectorMock.Codeunit.al
+++ b/src/System Application/Test Library/File System/src/Mock/FileConnectorMock.Codeunit.al
@@ -8,7 +8,7 @@ namespace System.TestLibraries.FileSystem;
using System.FileSystem;
using System.TestLibraries.Utilities;
-codeunit 80200 "Connector Mock"
+codeunit 134760 "File Connector Mock"
{
var
Any: Codeunit Any;
diff --git a/src/System Application/Test Library/File System/src/Mock/FileScenarioMock.Codeunit.al b/src/System Application/Test Library/File System/src/Mock/FileScenarioMock.Codeunit.al
index 47a53ada2b..51a0e32d63 100644
--- a/src/System Application/Test Library/File System/src/Mock/FileScenarioMock.Codeunit.al
+++ b/src/System Application/Test Library/File System/src/Mock/FileScenarioMock.Codeunit.al
@@ -7,7 +7,7 @@ namespace System.TestLibraries.FileSystem;
using System.FileSystem;
-codeunit 80201 "File Scenario Mock"
+codeunit 134761 "File Scenario Mock"
{
Permissions = tabledata "File Scenario" = rid;
diff --git a/src/System Application/Test Library/File System/src/TestFileSystemConnector.Codeunit.al b/src/System Application/Test Library/File System/src/TestFileSystemConnector.Codeunit.al
index 7c9dc820d2..c4ae847d2d 100644
--- a/src/System Application/Test Library/File System/src/TestFileSystemConnector.Codeunit.al
+++ b/src/System Application/Test Library/File System/src/TestFileSystemConnector.Codeunit.al
@@ -74,7 +74,7 @@ codeunit 80202 "Test File System Connector" implements "File System Connector"
procedure GetAccounts(var Accounts: Record "File Account")
begin
- ConnectorMock.GetAccounts(Accounts);
+ FileConnectorMock.GetAccounts(Accounts);
end;
procedure ShowAccountInformation(AccountId: Guid)
@@ -85,10 +85,10 @@ codeunit 80202 "Test File System Connector" implements "File System Connector"
procedure RegisterAccount(var FileAccount: Record "File Account"): Boolean
var
begin
- if ConnectorMock.FailOnRegisterAccount() then
+ if FileConnectorMock.FailOnRegisterAccount() then
Error('Failed to register account');
- if ConnectorMock.UnsuccessfulRegister() then
+ if FileConnectorMock.UnsuccessfulRegister() then
exit(false);
FileAccount."Account Id" := CreateGuid();
@@ -117,5 +117,5 @@ codeunit 80202 "Test File System Connector" implements "File System Connector"
end;
var
- ConnectorMock: Codeunit "Connector Mock";
+ FileConnectorMock: Codeunit "File Connector Mock";
}
\ No newline at end of file
diff --git a/src/System Application/Test/File System/src/FileAccountsTest.Codeunit.al b/src/System Application/Test/File System/src/FileAccountsTest.Codeunit.al
index 60cec7cc4e..7f4ae74727 100644
--- a/src/System Application/Test/File System/src/FileAccountsTest.Codeunit.al
+++ b/src/System Application/Test/File System/src/FileAccountsTest.Codeunit.al
@@ -10,7 +10,7 @@ using System.TestLibraries.FileSystem;
using System.TestLibraries.Utilities;
using System.TestLibraries.Security.AccessControl;
-codeunit 134686 "File Accounts Test"
+codeunit 134750 "File Accounts Test"
{
Subtype = Test;
TestPermissions = Disabled;
@@ -27,14 +27,14 @@ codeunit 134686 "File Accounts Test"
procedure AccountsAppearOnThePageTest()
var
FileAccount: Record "File Account";
- ConnectorMock: Codeunit "Connector Mock";
+ FileConnectorMock: Codeunit "File Connector Mock";
AccountsPage: TestPage "File Accounts";
begin
// [Scenario] When there's a File account for a connector, it appears on the accounts page
// [Given] A File account
- ConnectorMock.Initialize();
- ConnectorMock.AddAccount(FileAccount);
+ FileConnectorMock.Initialize();
+ FileConnectorMock.AddAccount(FileAccount);
PermissionsMock.Set('File System Edit');
@@ -53,15 +53,15 @@ codeunit 134686 "File Accounts Test"
procedure TwoAccountsAppearOnThePageTest()
var
FirstFileAccount, SecondFileAccount : Record "File Account";
- ConnectorMock: Codeunit "Connector Mock";
+ FileConnectorMock: Codeunit "File Connector Mock";
AccountsPage: TestPage "File Accounts";
begin
// [Scenario] When there's a File account for a connector, it appears on the accounts page
// [Given] Two File accounts
- ConnectorMock.Initialize();
- ConnectorMock.AddAccount(FirstFileAccount);
- ConnectorMock.AddAccount(SecondFileAccount);
+ FileConnectorMock.Initialize();
+ FileConnectorMock.AddAccount(FirstFileAccount);
+ FileConnectorMock.AddAccount(SecondFileAccount);
PermissionsMock.Set('File System Edit');
@@ -81,13 +81,13 @@ codeunit 134686 "File Accounts Test"
[TransactionModel(TransactionModel::AutoRollback)]
procedure AddNewAccountTest()
var
- ConnectorMock: Codeunit "Connector Mock";
+ FileConnectorMock: Codeunit "File Connector Mock";
AccountWizardPage: TestPage "File Account Wizard";
begin
// [SCENARIO] A new Account can be added through the Account Wizard
PermissionsMock.Set('File System Admin');
- ConnectorMock.Initialize();
+ FileConnectorMock.Initialize();
// [WHEN] The AddAccount action is invoked
AccountWizardPage.Trap();
@@ -133,13 +133,13 @@ codeunit 134686 "File Accounts Test"
procedure GetAllAccountsTest()
var
FileAccountBuffer, FileAccounts : Record "File Account";
- ConnectorMock: Codeunit "Connector Mock";
+ FileConnectorMock: Codeunit "File Connector Mock";
FileAccount: Codeunit "File Account";
begin
// [SCENARIO] GetAllAccounts retrieves all the registered accounts
// [GIVEN] A connector is installed and no account is added
- ConnectorMock.Initialize();
+ FileConnectorMock.Initialize();
PermissionsMock.Set('File System Edit');
@@ -150,7 +150,7 @@ codeunit 134686 "File Accounts Test"
Assert.IsTrue(FileAccounts.IsEmpty(), 'Record should be empty');
// [GIVEN] An account is added to the connector
- ConnectorMock.AddAccount(FileAccountBuffer);
+ FileConnectorMock.AddAccount(FileAccountBuffer);
// [WHEN] GetAllAccounts is called
FileAccount.GetAllAccounts(FileAccounts);
@@ -166,14 +166,14 @@ codeunit 134686 "File Accounts Test"
[Test]
procedure IsAnyAccountRegisteredTest()
var
- ConnectorMock: Codeunit "Connector Mock";
+ FileConnectorMock: Codeunit "File Connector Mock";
FileAccount: Codeunit "File Account";
AccountId: Guid;
begin
// [SCENARIO] File Account Exists works as expected
// [GIVEN] A connector is installed and no account is added
- ConnectorMock.Initialize();
+ FileConnectorMock.Initialize();
PermissionsMock.Set('File System Edit');
@@ -182,7 +182,7 @@ codeunit 134686 "File Accounts Test"
Assert.IsFalse(FileAccount.IsAnyAccountRegistered(), 'There should be no registered accounts');
// [WHEN] An File account is added
- ConnectorMock.AddAccount(AccountId);
+ FileConnectorMock.AddAccount(AccountId);
// [WHEN] Calling IsAnyAccountRegistered
// [THEN] it evaluates to true
@@ -193,7 +193,7 @@ codeunit 134686 "File Accounts Test"
[HandlerFunctions('ConfirmYesHandler')]
procedure DeleteAllAccountsTest()
var
- ConnectorMock: Codeunit "Connector Mock";
+ FileConnectorMock: Codeunit "File Connector Mock";
FileAccountsSelectionMock: Codeunit "File System Acc Selection Mock";
FirstAccountId, SecondAccountId, ThirdAccountId : Guid;
FileAccountsTestPage: TestPage "File Accounts";
@@ -202,10 +202,10 @@ codeunit 134686 "File Accounts Test"
PermissionsMock.Set('File System Admin');
// [GIVEN] A connector is installed and three account are added
- ConnectorMock.Initialize();
- ConnectorMock.AddAccount(FirstAccountId);
- ConnectorMock.AddAccount(SecondAccountId);
- ConnectorMock.AddAccount(ThirdAccountId);
+ FileConnectorMock.Initialize();
+ FileConnectorMock.AddAccount(FirstAccountId);
+ FileConnectorMock.AddAccount(SecondAccountId);
+ FileConnectorMock.AddAccount(ThirdAccountId);
// [WHEN] Open the File Accounts page
FileAccountsTestPage.OpenView();
@@ -227,7 +227,7 @@ codeunit 134686 "File Accounts Test"
[HandlerFunctions('ConfirmNoHandler')]
procedure DeleteAllAccountsCancelTest()
var
- ConnectorMock: Codeunit "Connector Mock";
+ FileConnectorMock: Codeunit "File Connector Mock";
FileAccountsSelectionMock: Codeunit "File System Acc Selection Mock";
FirstAccountId, SecondAccountId, ThirdAccountId : Guid;
FileAccountsTestPage: TestPage "File Accounts";
@@ -236,10 +236,10 @@ codeunit 134686 "File Accounts Test"
PermissionsMock.Set('File System Admin');
// [GIVEN] A connector is installed and three account are added
- ConnectorMock.Initialize();
- ConnectorMock.AddAccount(FirstAccountId);
- ConnectorMock.AddAccount(SecondAccountId);
- ConnectorMock.AddAccount(ThirdAccountId);
+ FileConnectorMock.Initialize();
+ FileConnectorMock.AddAccount(FirstAccountId);
+ FileConnectorMock.AddAccount(SecondAccountId);
+ FileConnectorMock.AddAccount(ThirdAccountId);
// [WHEN] Open the File Accounts page
FileAccountsTestPage.OpenView();
@@ -263,7 +263,7 @@ codeunit 134686 "File Accounts Test"
[HandlerFunctions('ConfirmYesHandler')]
procedure DeleteSomeAccountsTest()
var
- ConnectorMock: Codeunit "Connector Mock";
+ FileConnectorMock: Codeunit "File Connector Mock";
FileAccountsSelectionMock: Codeunit "File System Acc Selection Mock";
FirstAccountId, SecondAccountId, ThirdAccountId : Guid;
FileAccountsTestPage: TestPage "File Accounts";
@@ -272,10 +272,10 @@ codeunit 134686 "File Accounts Test"
PermissionsMock.Set('File System Admin');
// [GIVEN] A connector is installed and three account are added
- ConnectorMock.Initialize();
- ConnectorMock.AddAccount(FirstAccountId);
- ConnectorMock.AddAccount(SecondAccountId);
- ConnectorMock.AddAccount(ThirdAccountId);
+ FileConnectorMock.Initialize();
+ FileConnectorMock.AddAccount(FirstAccountId);
+ FileConnectorMock.AddAccount(SecondAccountId);
+ FileConnectorMock.AddAccount(ThirdAccountId);
// [WHEN] Open the File Accounts page
FileAccountsTestPage.OpenView();
@@ -299,7 +299,7 @@ codeunit 134686 "File Accounts Test"
procedure DeleteNonDefaultAccountTest()
var
SecondAccount: Record "File Account";
- ConnectorMock: Codeunit "Connector Mock";
+ FileConnectorMock: Codeunit "File Connector Mock";
FileAccountsSelectionMock: Codeunit "File System Acc Selection Mock";
FileScenario: Codeunit "File Scenario";
FirstAccountId, ThirdAccountId : Guid;
@@ -309,10 +309,10 @@ codeunit 134686 "File Accounts Test"
PermissionsMock.Set('File System Admin');
// [GIVEN] A connector is installed and three account are added
- ConnectorMock.Initialize();
- ConnectorMock.AddAccount(FirstAccountId);
- ConnectorMock.AddAccount(SecondAccount);
- ConnectorMock.AddAccount(ThirdAccountId);
+ FileConnectorMock.Initialize();
+ FileConnectorMock.AddAccount(FirstAccountId);
+ FileConnectorMock.AddAccount(SecondAccount);
+ FileConnectorMock.AddAccount(ThirdAccountId);
// [GIVEN] The second account is set as default
FileScenario.SetDefaultFileAccount(SecondAccount);
@@ -342,7 +342,7 @@ codeunit 134686 "File Accounts Test"
procedure DeleteDefaultAccountTest()
var
SecondAccount: Record "File Account";
- ConnectorMock: Codeunit "Connector Mock";
+ FileConnectorMock: Codeunit "File Connector Mock";
FileAccountsSelectionMock: Codeunit "File System Acc Selection Mock";
FileScenario: Codeunit "File Scenario";
FirstAccountId, ThirdAccountId : Guid;
@@ -352,10 +352,10 @@ codeunit 134686 "File Accounts Test"
PermissionsMock.Set('File System Admin');
// [GIVEN] A connector is installed and three account are added
- ConnectorMock.Initialize();
- ConnectorMock.AddAccount(FirstAccountId);
- ConnectorMock.AddAccount(SecondAccount);
- ConnectorMock.AddAccount(ThirdAccountId);
+ FileConnectorMock.Initialize();
+ FileConnectorMock.AddAccount(FirstAccountId);
+ FileConnectorMock.AddAccount(SecondAccount);
+ FileConnectorMock.AddAccount(ThirdAccountId);
// [GIVEN] The second account is set as default
FileScenario.SetDefaultFileAccount(SecondAccount);
@@ -384,7 +384,7 @@ codeunit 134686 "File Accounts Test"
procedure DeleteDefaultAccountPromptNewAccountCancelTest()
var
SecondAccount: Record "File Account";
- ConnectorMock: Codeunit "Connector Mock";
+ FileConnectorMock: Codeunit "File Connector Mock";
FileAccountsSelectionMock: Codeunit "File System Acc Selection Mock";
FileScenario: Codeunit "File Scenario";
FirstAccountId, ThirdAccountId : Guid;
@@ -394,10 +394,10 @@ codeunit 134686 "File Accounts Test"
PermissionsMock.Set('File System Admin');
// [GIVEN] A connector is installed and three account are added
- ConnectorMock.Initialize();
- ConnectorMock.AddAccount(FirstAccountId);
- ConnectorMock.AddAccount(SecondAccount);
- ConnectorMock.AddAccount(ThirdAccountId);
+ FileConnectorMock.Initialize();
+ FileConnectorMock.AddAccount(FirstAccountId);
+ FileConnectorMock.AddAccount(SecondAccount);
+ FileConnectorMock.AddAccount(ThirdAccountId);
// [GIVEN] The second account is set as default
FileScenario.SetDefaultFileAccount(SecondAccount);
@@ -428,7 +428,7 @@ codeunit 134686 "File Accounts Test"
procedure DeleteDefaultAccountPromptNewAccountTest()
var
SecondAccount: Record "File Account";
- ConnectorMock: Codeunit "Connector Mock";
+ FileConnectorMock: Codeunit "File Connector Mock";
FileAccountsSelectionMock: Codeunit "File System Acc Selection Mock";
FileScenario: Codeunit "File Scenario";
FirstAccountId, ThirdAccountId : Guid;
@@ -438,10 +438,10 @@ codeunit 134686 "File Accounts Test"
PermissionsMock.Set('File System Admin');
// [GIVEN] A connector is installed and three account are added
- ConnectorMock.Initialize();
- ConnectorMock.AddAccount(FirstAccountId);
- ConnectorMock.AddAccount(SecondAccount);
- ConnectorMock.AddAccount(ThirdAccountId);
+ FileConnectorMock.Initialize();
+ FileConnectorMock.AddAccount(FirstAccountId);
+ FileConnectorMock.AddAccount(SecondAccount);
+ FileConnectorMock.AddAccount(ThirdAccountId);
// [GIVEN] The second account is set as default
FileScenario.SetDefaultFileAccount(SecondAccount);
diff --git a/src/System Application/Test/File System/src/FileScenarioPageTest.Codeunit.al b/src/System Application/Test/File System/src/FileScenarioPageTest.Codeunit.al
index c93b0dc990..8d16e5767b 100644
--- a/src/System Application/Test/File System/src/FileScenarioPageTest.Codeunit.al
+++ b/src/System Application/Test/File System/src/FileScenarioPageTest.Codeunit.al
@@ -10,13 +10,13 @@ using System.FileSystem;
using System.TestLibraries.Utilities;
using System.TestLibraries.Security.AccessControl;
-codeunit 134695 "File Scenario Page Test"
+codeunit 134751 "File Scenario Page Test"
{
Subtype = Test;
var
Assert: Codeunit "Library Assert";
- ConnectorMock: Codeunit "Connector Mock";
+ FileConnectorMock: Codeunit "File Connector Mock";
FileScenarioMock: Codeunit "File Scenario Mock";
PermissionsMock: Codeunit "Permissions Mock";
DisplayNameTxt: Label '%1', Locked = true;
@@ -33,7 +33,7 @@ codeunit 134695 "File Scenario Page Test"
PermissionsMock.Set('File System Admin');
// [Given] No file account is registered.
- ConnectorMock.Initialize();
+ FileConnectorMock.Initialize();
// [When] Opening the the page
FileScenarioPage.Trap();
@@ -55,8 +55,8 @@ codeunit 134695 "File Scenario Page Test"
PermissionsMock.Set('File System Admin');
// [Given] One file account is registered.
- ConnectorMock.Initialize();
- ConnectorMock.AddAccount(FileAccount);
+ FileConnectorMock.Initialize();
+ FileConnectorMock.AddAccount(FileAccount);
// [When] Opening the the page
FileScenarioPage.Trap();
@@ -88,8 +88,8 @@ codeunit 134695 "File Scenario Page Test"
PermissionsMock.Set('File System Admin');
// [Given] One file account is registered and it's set as default.
- ConnectorMock.Initialize();
- ConnectorMock.AddAccount(FileAccount);
+ FileConnectorMock.Initialize();
+ FileConnectorMock.AddAccount(FileAccount);
FileScenarioMock.DeleteAllMappings();
FileScenarioMock.AddMapping(Enum::"File Scenario"::Default, FileAccount."Account Id", FileAccount.Connector);
@@ -126,8 +126,8 @@ codeunit 134695 "File Scenario Page Test"
PermissionsMock.Set('File System Admin');
// [Given] One file account is registered and it's set as default.
- ConnectorMock.Initialize();
- ConnectorMock.AddAccount(FileAccount);
+ FileConnectorMock.Initialize();
+ FileConnectorMock.AddAccount(FileAccount);
FileScenarioMock.DeleteAllMappings();
FileScenarioMock.AddMapping(Enum::"File Scenario"::Default, FileAccount."Account Id", FileAccount.Connector);
@@ -174,9 +174,9 @@ codeunit 134695 "File Scenario Page Test"
PermissionsMock.Set('File System Admin');
// [Given] Two file accounts are registered. One is set as default.
- ConnectorMock.Initialize();
- ConnectorMock.AddAccount(FirstFileAccount);
- ConnectorMock.AddAccount(SecondFileAccount);
+ FileConnectorMock.Initialize();
+ FileConnectorMock.AddAccount(FirstFileAccount);
+ FileConnectorMock.AddAccount(SecondFileAccount);
FileScenarioMock.DeleteAllMappings();
FileScenarioMock.AddMapping(Enum::"File Scenario"::Default, FirstFileAccount."Account Id", FirstFileAccount.Connector);
diff --git a/src/System Application/Test/File System/src/FileScenarioTest.Codeunit.al b/src/System Application/Test/File System/src/FileScenarioTest.Codeunit.al
index 8435cee09f..6d34e65685 100644
--- a/src/System Application/Test/File System/src/FileScenarioTest.Codeunit.al
+++ b/src/System Application/Test/File System/src/FileScenarioTest.Codeunit.al
@@ -10,14 +10,14 @@ using System.TestLibraries.FileSystem;
using System.TestLibraries.Utilities;
using System.TestLibraries.Security.AccessControl;
-codeunit 134693 "File Scenario Test"
+codeunit 134752 "File Scenario Test"
{
Subtype = Test;
var
Assert: Codeunit "Library Assert";
Any: Codeunit Any;
- ConnectorMock: Codeunit "Connector Mock";
+ FileConnectorMock: Codeunit "File Connector Mock";
FileScenarioMock: Codeunit "File Scenario Mock";
FileScenario: Codeunit "File Scenario";
PermissionsMock: Codeunit "Permissions Mock";
@@ -91,7 +91,7 @@ codeunit 134693 "File Scenario Test"
// [Given] An File scenario isn't mapped to an account and the default scenario is mapped to an existing account
Initialize();
- ConnectorMock.AddAccount(AccountId);
+ FileConnectorMock.AddAccount(AccountId);
FileScenarioMock.AddMapping(Enum::"File Scenario"::Default, AccountId, Enum::"File System Connector"::"Test File System Connector");
// [When] calling GetFileAccount
@@ -113,7 +113,7 @@ codeunit 134693 "File Scenario Test"
// [Given] An File scenario is mapped to an account
Initialize();
- ConnectorMock.AddAccount(AccountId);
+ FileConnectorMock.AddAccount(AccountId);
FileScenarioMock.AddMapping(Enum::"File Scenario"::"Test File Scenario", AccountId, Enum::"File System Connector"::"Test File System Connector");
// [When] calling GetFileAccount
@@ -136,8 +136,8 @@ codeunit 134693 "File Scenario Test"
// [Given] An File scenario is mapped to an account, the default scenarion is mapped to another account
Initialize();
- ConnectorMock.AddAccount(AccountId);
- ConnectorMock.AddAccount(DefaultAccountId);
+ FileConnectorMock.AddAccount(AccountId);
+ FileConnectorMock.AddAccount(DefaultAccountId);
FileScenarioMock.AddMapping(Enum::"File Scenario"::"Test File Scenario", AccountId, Enum::"File System Connector"::"Test File System Connector");
FileScenarioMock.AddMapping(Enum::"File Scenario"::Default, DefaultAccountId, Enum::"File System Connector"::"Test File System Connector");
@@ -165,7 +165,7 @@ codeunit 134693 "File Scenario Test"
// [Given] An File scenario is mapped to a non-exisitng account, the default scenarion is mapped to an existing account
Initialize();
- ConnectorMock.AddAccount(DefaultAccountId);
+ FileConnectorMock.AddAccount(DefaultAccountId);
NonExistingAccountId := Any.GuidValue();
FileScenarioMock.AddMapping(Enum::"File Scenario"::"Test File Scenario", NonExistingAccountId, Enum::"File System Connector"::"Test File System Connector");
FileScenarioMock.AddMapping(Enum::"File Scenario"::Default, DefaultAccountId, Enum::"File System Connector"::"Test File System Connector");
@@ -194,7 +194,7 @@ codeunit 134693 "File Scenario Test"
// [Given] An File scenario is mapped to an exisitng account, the default scenarion is mapped to a non-existing account
Initialize();
- ConnectorMock.AddAccount(AccountId);
+ FileConnectorMock.AddAccount(AccountId);
DefaultAccountId := Any.GuidValue();
FileScenarioMock.AddMapping(Enum::"File Scenario"::"Test File Scenario", AccountId, Enum::"File System Connector"::"Test File System Connector");
FileScenarioMock.AddMapping(Enum::"File Scenario"::Default, DefaultAccountId, Enum::"File System Connector"::"Test File System Connector");
@@ -262,8 +262,8 @@ codeunit 134693 "File Scenario Test"
// [Given] Two accounts, one default and one not
Initialize();
- ConnectorMock.AddAccount(FileAccount);
- ConnectorMock.AddAccount(DefaultAccount);
+ FileConnectorMock.AddAccount(FileAccount);
+ FileConnectorMock.AddAccount(DefaultAccount);
FileScenario.SetDefaultFileAccount(DefaultAccount);
FileScenario.SetFileAccount(Enum::"File Scenario"::"Test File Scenario", FileAccount);
From 0cfd765cfb3136276bf902f126b02f71649f6e5a Mon Sep 17 00:00:00 2001
From: Thomas Williamson
Date: Wed, 10 Apr 2024 11:34:01 +0200
Subject: [PATCH 13/43] Fix test
---
.../Test/File System/src/FileScenarioTest.Codeunit.al | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/System Application/Test/File System/src/FileScenarioTest.Codeunit.al b/src/System Application/Test/File System/src/FileScenarioTest.Codeunit.al
index 6d34e65685..6d6a4f7862 100644
--- a/src/System Application/Test/File System/src/FileScenarioTest.Codeunit.al
+++ b/src/System Application/Test/File System/src/FileScenarioTest.Codeunit.al
@@ -235,7 +235,7 @@ codeunit 134752 "File Scenario Test"
// [Then] The scenario exists and is as expected
Assert.IsTrue(FileSystemTestLib.GetFileScenarioAccountIdAndFileConnector(Scenario, AccountId, FileSystemConnector), 'The File scenario should exist');
Assert.AreEqual(AccountId, FileAccount."Account Id", 'Wrong accound ID');
- Assert.AreEqual(FileSystemConnector, FileAccount.Connector, 'Wrong connector');
+ Assert.AreEqual(Enum::"File System Connector"::"Test File System Connector", FileAccount.Connector, 'Wrong connector');
AnotherAccount."Account Id" := Any.GuidValue();
AnotherAccount.Connector := Enum::"File System Connector"::"Test File System Connector";
@@ -246,7 +246,7 @@ codeunit 134752 "File Scenario Test"
// [Then] The scenario still exists and is as expected
Assert.IsTrue(FileSystemTestLib.GetFileScenarioAccountIdAndFileConnector(Scenario, AccountId, FileSystemConnector), 'The File scenario should exist');
Assert.AreEqual(AccountId, AnotherAccount."Account Id", 'Wrong accound ID');
- Assert.AreEqual(FileSystemConnector, AnotherAccount.Connector, 'Wrong connector');
+ Assert.AreEqual(Enum::"File System Connector"::"Test File System Connector", AnotherAccount.Connector, 'Wrong connector');
end;
[Test]
From 03272202e2e0b1e46bd8bbac67fafb98235277f0 Mon Sep 17 00:00:00 2001
From: Thomas Williamson
Date: Mon, 10 Jun 2024 08:48:28 +0200
Subject: [PATCH 14/43] Fix application areas
---
.../File System/src/Account/FileAccountWizard.Page.al | 10 ----------
.../App/File System/src/Account/FileAccounts.Page.al | 1 +
2 files changed, 1 insertion(+), 10 deletions(-)
diff --git a/src/System Application/App/File System/src/Account/FileAccountWizard.Page.al b/src/System Application/App/File System/src/Account/FileAccountWizard.Page.al
index 3cd716b6db..d8b7046648 100644
--- a/src/System Application/App/File System/src/Account/FileAccountWizard.Page.al
+++ b/src/System Application/App/File System/src/Account/FileAccountWizard.Page.al
@@ -43,7 +43,6 @@ page 9451 "File Account Wizard"
Visible = not DoneVisible and TopBannerVisible;
field(NotDoneIcon; MediaResourcesStandard."Media Reference")
{
- ApplicationArea = All;
Editable = false;
ShowCaption = false;
ToolTip = ' ';
@@ -57,7 +56,6 @@ page 9451 "File Account Wizard"
Visible = DoneVisible and TopBannerVisible;
field(DoneIcon; MediaResourcesDone."Media Reference")
{
- ApplicationArea = All;
Editable = false;
ShowCaption = false;
ToolTip = ' ';
@@ -198,13 +196,11 @@ page 9451 "File Account Wizard"
label(NoConnectorsAvailable3)
{
- ApplicationArea = All;
Caption = 'View a list of the available file apps';
}
field(LearnMore; LearnMoreTok)
{
- ApplicationArea = All;
Editable = false;
ShowCaption = false;
Caption = ' ';
@@ -232,7 +228,6 @@ page 9451 "File Account Wizard"
Caption = 'Account';
field(Namefield; RegisteredAccount.Name)
{
- ApplicationArea = All;
Editable = false;
Caption = 'Name';
ToolTip = 'Specifies the name of the account registered.';
@@ -245,7 +240,6 @@ page 9451 "File Account Wizard"
field(DefaultField; SetAsDefault)
{
- ApplicationArea = All;
Editable = true;
Enabled = true;
Caption = 'Set as default';
@@ -263,7 +257,6 @@ page 9451 "File Account Wizard"
action(Cancel)
{
- ApplicationArea = All;
Visible = CancelActionVisible;
Caption = 'Cancel';
ToolTip = 'Cancel';
@@ -278,7 +271,6 @@ page 9451 "File Account Wizard"
action(Back)
{
- ApplicationArea = All;
Visible = BackActionVisible;
Enabled = BackActionEnabled;
Caption = 'Back';
@@ -294,7 +286,6 @@ page 9451 "File Account Wizard"
action(Next)
{
- ApplicationArea = All;
Visible = NextActionVisible;
Enabled = NextActionEnabled;
Caption = 'Next';
@@ -310,7 +301,6 @@ page 9451 "File Account Wizard"
action(Finish)
{
- ApplicationArea = All;
Visible = FinishActionVisible;
Caption = 'Finish';
ToolTip = 'Finish';
diff --git a/src/System Application/App/File System/src/Account/FileAccounts.Page.al b/src/System Application/App/File System/src/Account/FileAccounts.Page.al
index bdb4739d29..b1836c1d60 100644
--- a/src/System Application/App/File System/src/Account/FileAccounts.Page.al
+++ b/src/System Application/App/File System/src/Account/FileAccounts.Page.al
@@ -14,6 +14,7 @@ page 9450 "File Accounts"
{
PageType = List;
Caption = 'File Accounts';
+ ApplicationArea = All;
UsageCategory = Administration;
SourceTable = "File Account";
SourceTableTemporary = true;
From 0ec94d8b0b4876e239f1a5fc0ea39f0596fc00d2 Mon Sep 17 00:00:00 2001
From: Thomas Williamson
Date: Mon, 10 Jun 2024 08:49:58 +0200
Subject: [PATCH 15/43] Remove unused label
---
.../App/File System/src/Scenario/FileScenarioImpl.Codeunit.al | 1 -
1 file changed, 1 deletion(-)
diff --git a/src/System Application/App/File System/src/Scenario/FileScenarioImpl.Codeunit.al b/src/System Application/App/File System/src/Scenario/FileScenarioImpl.Codeunit.al
index bf6932665b..632b439119 100644
--- a/src/System Application/App/File System/src/Scenario/FileScenarioImpl.Codeunit.al
+++ b/src/System Application/App/File System/src/Scenario/FileScenarioImpl.Codeunit.al
@@ -323,7 +323,6 @@ codeunit 9453 "File Scenario Impl."
var
FileAccountImpl: Codeunit "File Account Impl.";
- AccountDisplayLbl: Label '%1 (%2)', Locked = true;
ChangeFileAccountForScenarioTxt: Label 'Change file account used for the selected scenarios';
ScenariosForAccountCaptionTxt: Label 'Assign scenarios to account %1', Comment = '%1 = the name of the e-file account';
}
\ No newline at end of file
From 6f742e4300f9492400d2ae29721b17fc318c3698 Mon Sep 17 00:00:00 2001
From: Thomas Williamson
Date: Mon, 10 Jun 2024 08:51:46 +0200
Subject: [PATCH 16/43] Simplify integer incrementation
---
.../App/File System/src/Scenario/FileScenarioImpl.Codeunit.al | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/System Application/App/File System/src/Scenario/FileScenarioImpl.Codeunit.al b/src/System Application/App/File System/src/Scenario/FileScenarioImpl.Codeunit.al
index 632b439119..33972ff4d5 100644
--- a/src/System Application/App/File System/src/Scenario/FileScenarioImpl.Codeunit.al
+++ b/src/System Application/App/File System/src/Scenario/FileScenarioImpl.Codeunit.al
@@ -245,7 +245,7 @@ codeunit 9453 "File Scenario Impl."
FileScenarios.Insert();
end;
- i := i + 1;
+ i += 1;
end;
end;
From 33afd8318cdef0660b775e363c24a99cbb99e796 Mon Sep 17 00:00:00 2001
From: Thomas Williamson
Date: Mon, 10 Jun 2024 08:54:44 +0200
Subject: [PATCH 17/43] Sort variables
---
.../App/File System/src/Account/FileAccounts.Page.al | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/src/System Application/App/File System/src/Account/FileAccounts.Page.al b/src/System Application/App/File System/src/Account/FileAccounts.Page.al
index b1836c1d60..0ceafb4928 100644
--- a/src/System Application/App/File System/src/Account/FileAccounts.Page.al
+++ b/src/System Application/App/File System/src/Account/FileAccounts.Page.al
@@ -263,8 +263,8 @@ page 9450 "File Accounts"
var
FileAccount: Codeunit "File Account";
FileScenario: Codeunit "File Scenario";
- IsSelected: Boolean;
SelectedAccountId: Guid;
+ IsSelected: Boolean;
begin
// We need this code block to maintain the same selected record.
SelectedAccountId := Rec."Account Id";
@@ -330,12 +330,12 @@ page 9450 "File Accounts"
var
DefaultFileAccount: Record "File Account";
FileAccountImpl: Codeunit "File Account Impl.";
- IsDefault: Boolean;
CanUserManageFileSetup: Boolean;
- DefaultTxt: Text;
- UpdateAccounts: Boolean;
- ShowLogo: Boolean;
- IsInLookupMode: Boolean;
HasFileAccount: Boolean;
+ IsDefault: Boolean;
+ IsInLookupMode: Boolean;
+ ShowLogo: Boolean;
+ UpdateAccounts: Boolean;
+ DefaultTxt: Text;
FileConnectorHasBeenUninstalledMsg: Label 'The selected file extension has been uninstalled. To view information about the file account, you must reinstall the extension.';
}
\ No newline at end of file
From f701d9f2edecb212ce9a82f6f36a05eaed3afb2f Mon Sep 17 00:00:00 2001
From: Thomas Williamson
Date: Mon, 10 Jun 2024 10:11:12 +0200
Subject: [PATCH 18/43] Add Init to AddEntry
---
.../App/File System/src/Scenario/FileScenarioImpl.Codeunit.al | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/System Application/App/File System/src/Scenario/FileScenarioImpl.Codeunit.al b/src/System Application/App/File System/src/Scenario/FileScenarioImpl.Codeunit.al
index 33972ff4d5..a868d3c095 100644
--- a/src/System Application/App/File System/src/Scenario/FileScenarioImpl.Codeunit.al
+++ b/src/System Application/App/File System/src/Scenario/FileScenarioImpl.Codeunit.al
@@ -158,6 +158,7 @@ codeunit 9453 "File Scenario Impl."
local procedure AddEntry(var Result: Record "File Account Scenario"; EntryType: Option; Scenario: Integer; AccountId: Guid; Connector: Enum "File System Connector"; DisplayName: Text[2048]; Default: Boolean; var Position: Integer)
begin
// Add entry to the result while maintaining the position so that the tree represents the data correctly
+ Result.Init();
Result.EntryType := EntryType;
Result.Scenario := Scenario;
Result."Account Id" := AccountId;
@@ -165,7 +166,6 @@ codeunit 9453 "File Scenario Impl."
Result."Display Name" := DisplayName;
Result.Default := Default;
Result.Position := Position;
-
Result.Insert();
Position := Position + 1;
From c3cd8b5bcec50f13af9d950b9f2592b1f342b53a Mon Sep 17 00:00:00 2001
From: Thomas Williamson
Date: Mon, 10 Jun 2024 10:13:29 +0200
Subject: [PATCH 19/43] Change tooltip to code review suggestion
---
.../App/File System/src/Account/FileAccounts.Page.al | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/System Application/App/File System/src/Account/FileAccounts.Page.al b/src/System Application/App/File System/src/Account/FileAccounts.Page.al
index 0ceafb4928..cce39aded4 100644
--- a/src/System Application/App/File System/src/Account/FileAccounts.Page.al
+++ b/src/System Application/App/File System/src/Account/FileAccounts.Page.al
@@ -108,7 +108,7 @@ page 9450 "File Accounts"
{
Image = Add;
Caption = 'Add an file account';
- ToolTip = 'Add an file account.';
+ ToolTip = 'Opens a File Account Wizard setup page in order to add an File Account.';
Visible = (not IsInLookupMode) and CanUserManageFileSetup;
trigger OnAction()
From a53d93670b5eba090561f71a2f65b2276dbfa236 Mon Sep 17 00:00:00 2001
From: Thomas Williamson
Date: Fri, 23 Aug 2024 18:30:38 +0200
Subject: [PATCH 20/43] Solve code review comments
---
.../permissions/FileSystemEdit.PermissionSet.al | 16 +++++++---------
.../permissions/FileSystemRead.PermissionSet.al | 16 +++++++++-------
.../src/Account/FileAccountWizard.Page.al | 5 -----
.../File System/src/Account/FileAccounts.Page.al | 4 ----
...mp.Codeunit.al => FileSystemImpl.Codeunit.al} | 3 +--
.../src/Lookup/FileAccountBrowser.Page.al | 5 +++++
.../src/Lookup/FileAccountBrowserMgt.Codeunit.al | 12 +++++++-----
.../src/Lookup/FolderNameInput.Page.al | 1 +
.../src/Scenario/FileScenariosForAccount.Page.al | 1 +
.../src/UserSettingsImpl.Codeunit.al | 2 +-
10 files changed, 32 insertions(+), 33 deletions(-)
rename src/System Application/App/File System/src/FileSystem/{FileSystemImp.Codeunit.al => FileSystemImpl.Codeunit.al} (99%)
diff --git a/src/System Application/App/File System/permissions/FileSystemEdit.PermissionSet.al b/src/System Application/App/File System/permissions/FileSystemEdit.PermissionSet.al
index d0f2bffde8..5b9761bbb3 100644
--- a/src/System Application/App/File System/permissions/FileSystemEdit.PermissionSet.al
+++ b/src/System Application/App/File System/permissions/FileSystemEdit.PermissionSet.al
@@ -7,16 +7,14 @@ namespace System.FileSystem;
using System.Environment;
-permissionset 9451 "File System - Read"
+permissionset 9453 "File System - Edit"
{
- Access = Internal;
+ Access = Public;
Assignable = false;
+ Caption = 'File System - Edit';
- Permissions =
- tabledata "File System Connector" = r,
- tabledata "File System Connector Logo" = r,
- tabledata "File Account Scenario" = r,
- tabledata "File Scenario" = r,
- tabledata "File Account Content" = r,
- tabledata Media = r; // File System Account Wizard requires this
+ IncludedPermissionSets = "File System - Read";
+
+ Permissions = tabledata "File System Connector Logo" = imd,
+ tabledata "Tenant Media" = imd;
}
\ No newline at end of file
diff --git a/src/System Application/App/File System/permissions/FileSystemRead.PermissionSet.al b/src/System Application/App/File System/permissions/FileSystemRead.PermissionSet.al
index 5b9761bbb3..d0f2bffde8 100644
--- a/src/System Application/App/File System/permissions/FileSystemRead.PermissionSet.al
+++ b/src/System Application/App/File System/permissions/FileSystemRead.PermissionSet.al
@@ -7,14 +7,16 @@ namespace System.FileSystem;
using System.Environment;
-permissionset 9453 "File System - Edit"
+permissionset 9451 "File System - Read"
{
- Access = Public;
+ Access = Internal;
Assignable = false;
- Caption = 'File System - Edit';
- IncludedPermissionSets = "File System - Read";
-
- Permissions = tabledata "File System Connector Logo" = imd,
- tabledata "Tenant Media" = imd;
+ Permissions =
+ tabledata "File System Connector" = r,
+ tabledata "File System Connector Logo" = r,
+ tabledata "File Account Scenario" = r,
+ tabledata "File Scenario" = r,
+ tabledata "File Account Content" = r,
+ tabledata Media = r; // File System Account Wizard requires this
}
\ No newline at end of file
diff --git a/src/System Application/App/File System/src/Account/FileAccountWizard.Page.al b/src/System Application/App/File System/src/Account/FileAccountWizard.Page.al
index d8b7046648..764d393f8c 100644
--- a/src/System Application/App/File System/src/Account/FileAccountWizard.Page.al
+++ b/src/System Application/App/File System/src/Account/FileAccountWizard.Page.al
@@ -398,7 +398,6 @@ page 9451 "File Account Wizard"
local procedure ShowRegisterAccountStep()
var
FeatureTelemetry: Codeunit "Feature Telemetry";
- DefaultFileRateLimit: Integer;
AccountWasRegistered: Boolean;
ConnectorSucceeded: Boolean;
begin
@@ -442,7 +441,6 @@ page 9451 "File Account Wizard"
NextActionVisible := false;
CancelActionVisible := false;
FinishActionVisible := true;
- TestFileActionVisible := true;
end;
local procedure SetDefaultControls()
@@ -454,7 +452,6 @@ page 9451 "File Account Wizard"
NextActionEnabled := true;
CancelActionVisible := true;
FinishActionVisible := false;
- TestFileActionVisible := false;
// Groups
WelcomeVisible := false;
@@ -479,7 +476,6 @@ page 9451 "File Account Wizard"
[RunOnClient]
AppSource: DotNet AppSource;
Step: Option Welcome,"Choose Connector","Register Account",Done;
- RateLimit: Integer;
AppSourceTok: Label 'AppSource';
ExtensionManagementTok: Label 'Extension Management';
FileCategoryLbl: Label 'File', Locked = true;
@@ -497,7 +493,6 @@ page 9451 "File Account Wizard"
NextActionEnabled: Boolean;
CancelActionVisible: Boolean;
FinishActionVisible: Boolean;
- TestFileActionVisible: Boolean;
WelcomeVisible: Boolean;
ChooseConnectorVisible: Boolean;
DoneVisible: Boolean;
diff --git a/src/System Application/App/File System/src/Account/FileAccounts.Page.al b/src/System Application/App/File System/src/Account/FileAccounts.Page.al
index cce39aded4..02cc4a7fc0 100644
--- a/src/System Application/App/File System/src/Account/FileAccounts.Page.al
+++ b/src/System Application/App/File System/src/Account/FileAccounts.Page.al
@@ -279,14 +279,11 @@ page 9450 "File Accounts"
end else
if Rec.FindFirst() then;
- HasFileAccount := not Rec.IsEmpty();
-
CurrPage.Update(false);
end;
local procedure ShowAccountInformation()
var
- FileAccountImpl: Codeunit "File Account Impl.";
Connector: Interface "File System Connector";
begin
UpdateAccounts := true;
@@ -331,7 +328,6 @@ page 9450 "File Accounts"
DefaultFileAccount: Record "File Account";
FileAccountImpl: Codeunit "File Account Impl.";
CanUserManageFileSetup: Boolean;
- HasFileAccount: Boolean;
IsDefault: Boolean;
IsInLookupMode: Boolean;
ShowLogo: Boolean;
diff --git a/src/System Application/App/File System/src/FileSystem/FileSystemImp.Codeunit.al b/src/System Application/App/File System/src/FileSystem/FileSystemImpl.Codeunit.al
similarity index 99%
rename from src/System Application/App/File System/src/FileSystem/FileSystemImp.Codeunit.al
rename to src/System Application/App/File System/src/FileSystem/FileSystemImpl.Codeunit.al
index 6b4fadcfc2..66902ba06b 100644
--- a/src/System Application/App/File System/src/FileSystem/FileSystemImp.Codeunit.al
+++ b/src/System Application/App/File System/src/FileSystem/FileSystemImpl.Codeunit.al
@@ -12,8 +12,8 @@ codeunit 9455 "File System Impl."
InherentEntitlements = X;
var
- FileSystemConnector: Interface "File System Connector";
CurrFileAccount: Record "File Account";
+ FileSystemConnector: Interface "File System Connector";
IsInitialized: Boolean;
procedure Initialize(Scenario: Enum "File Scenario")
@@ -182,7 +182,6 @@ codeunit 9455 "File System Impl."
procedure SaveFileUI(Path: Text; FileExtension: Text; DialogTitle: Text): Text
var
- FileAccountContent: Record "File Account Content";
FileAccountBrowser: Page "File Account Browser";
FileName, FileNameWithExtenion : Text;
PleaseProvideFileExtensionErr: Label 'Please provide a valid file extension.';
diff --git a/src/System Application/App/File System/src/Lookup/FileAccountBrowser.Page.al b/src/System Application/App/File System/src/Lookup/FileAccountBrowser.Page.al
index 4a91904d20..ea8342bff6 100644
--- a/src/System Application/App/File System/src/Lookup/FileAccountBrowser.Page.al
+++ b/src/System Application/App/File System/src/Lookup/FileAccountBrowser.Page.al
@@ -17,6 +17,7 @@ page 9455 "File Account Browser"
Extensible = false;
InherentPermissions = X;
InherentEntitlements = X;
+ UsageCategory = None;
layout
{
@@ -62,6 +63,7 @@ page 9455 "File Account Browser"
field(SaveFileNameField; SaveFileName)
{
Caption = 'Filename';
+ ToolTip = 'Specifies the Name of the File.';
}
}
}
@@ -84,6 +86,7 @@ page 9455 "File Account Browser"
Ellipsis = true;
Visible = not IsInLookupMode;
Enabled = not IsInLookupMode;
+ ToolTip = 'Uploads a file to the current directory.';
trigger OnAction()
begin
@@ -98,6 +101,7 @@ page 9455 "File Account Browser"
Ellipsis = true;
Visible = not IsInLookupMode;
Enabled = not IsInLookupMode;
+ ToolTip = 'Creates a new directory in the current directory.';
trigger OnAction()
begin
@@ -112,6 +116,7 @@ page 9455 "File Account Browser"
Ellipsis = true;
Visible = not IsInLookupMode;
Enabled = not IsInLookupMode;
+ ToolTip = 'Deletes the selected file or directory.';
trigger OnAction()
begin
diff --git a/src/System Application/App/File System/src/Lookup/FileAccountBrowserMgt.Codeunit.al b/src/System Application/App/File System/src/Lookup/FileAccountBrowserMgt.Codeunit.al
index 4f1652ffae..52246f5819 100644
--- a/src/System Application/App/File System/src/Lookup/FileAccountBrowserMgt.Codeunit.al
+++ b/src/System Application/App/File System/src/Lookup/FileAccountBrowserMgt.Codeunit.al
@@ -45,9 +45,11 @@ codeunit 9458 "File Account Browser Mgt."
procedure DownloadFile(var TempFileAccountContent: Record "File Account Content" temporary)
var
Stream: InStream;
+ FileName: Text;
begin
FileSystem.GetFile(FileSystem.CombinePath(TempFileAccountContent."Parent Directory", TempFileAccountContent.Name), Stream);
- DownloadFromStream(Stream, '', '', '', TempFileAccountContent.Name);
+ FileName := TempFileAccountContent.Name;
+ DownloadFromStream(Stream, '', '', '', FileName);
end;
procedure UploadFile(Path: Text)
@@ -74,9 +76,9 @@ codeunit 9458 "File Account Browser Mgt."
FileSystem.CreateDirectory(FileSystem.CombinePath(Path, FolderName));
end;
- local procedure ListFiles(var FileAccountContent: Record "File Account Content" temporary; var Path: Text; DoNotLoadFields: Boolean; CurrentPath: Text; FileNameFilter: Text)
+ local procedure ListFiles(var FileAccountContent: Record "File Account Content" temporary; Path: Text; DoNotLoadFields: Boolean; CurrentPath: Text; FileNameFilter: Text)
var
- FileAccountContentToAdd: Record "File Account Content" temporary;
+ TempFileAccountContentToAdd: Record "File Account Content" temporary;
FilePaginationData: Codeunit "File Pagination Data";
begin
if DoNotLoadFields then
@@ -86,7 +88,7 @@ codeunit 9458 "File Account Browser Mgt."
FileSystem.ListFiles(Path, FilePaginationData, FileAccountContent);
until FilePaginationData.IsEndOfListing();
- AddFiles(FileAccountContent, FileAccountContentToAdd, CurrentPath, FileNameFilter);
+ AddFiles(FileAccountContent, TempFileAccountContentToAdd, CurrentPath, FileNameFilter);
end;
local procedure AddFiles(var FileAccountContent: Record "File Account Content" temporary; var FileAccountContentToAdd: Record "File Account Content" temporary; CurrentPath: Text; FileNameFilter: Text)
@@ -104,7 +106,7 @@ codeunit 9458 "File Account Browser Mgt."
FileAccountContent.Init();
FileAccountContent.Name := '..';
FileAccountContent.Type := FileAccountContent.Type::Directory;
- FileAccountContent."Parent Directory" := FileSystem.GetParentPath(CurrentPath);
+ FileAccountContent."Parent Directory" := CopyStr(FileSystem.GetParentPath(CurrentPath), 1, MaxStrLen(FileAccountContent."Parent Directory"));
FileAccountContent.Insert();
end;
diff --git a/src/System Application/App/File System/src/Lookup/FolderNameInput.Page.al b/src/System Application/App/File System/src/Lookup/FolderNameInput.Page.al
index 1ae4ff3532..42e4351ac0 100644
--- a/src/System Application/App/File System/src/Lookup/FolderNameInput.Page.al
+++ b/src/System Application/App/File System/src/Lookup/FolderNameInput.Page.al
@@ -21,6 +21,7 @@ page 9456 "Folder Name Input"
field(FolderNameField; FolderName)
{
Caption = 'Folder Name';
+ ToolTip = 'Specifies the Name of the directory.';
}
}
}
diff --git a/src/System Application/App/File System/src/Scenario/FileScenariosForAccount.Page.al b/src/System Application/App/File System/src/Scenario/FileScenariosForAccount.Page.al
index 47d26285c8..4f07b155b4 100644
--- a/src/System Application/App/File System/src/Scenario/FileScenariosForAccount.Page.al
+++ b/src/System Application/App/File System/src/Scenario/FileScenariosForAccount.Page.al
@@ -22,6 +22,7 @@ page 9454 "File Scenarios for Account"
LinksAllowed = false;
InherentPermissions = X;
InherentEntitlements = X;
+ UsageCategory = None;
layout
{
diff --git a/src/System Application/App/User Settings/src/UserSettingsImpl.Codeunit.al b/src/System Application/App/User Settings/src/UserSettingsImpl.Codeunit.al
index 03d8505e1d..3e5453c1a8 100644
--- a/src/System Application/App/User Settings/src/UserSettingsImpl.Codeunit.al
+++ b/src/System Application/App/User Settings/src/UserSettingsImpl.Codeunit.al
@@ -541,7 +541,7 @@ codeunit 9175 "User Settings Impl."
end;
end;
- [EventSubscriber(ObjectType::Codeunit, Codeunit::"System Action Triggers", 'GetIsLegacyActionBarEnabled', '', false, false)]
+ //[EventSubscriber(ObjectType::Codeunit, Codeunit::"System Action Triggers", 'GetIsLegacyActionBarEnabled', '', false, false)]
local procedure GetIsLegacyActionBarEnabled(var IsEnabled: Boolean)
begin
IsEnabled := IsLegacyActionBarEnabled(UserSecurityId());
From e6bf3444dc23a86cd8f240ae34196ade8df6368f Mon Sep 17 00:00:00 2001
From: Thomas Williamson
Date: Fri, 23 Aug 2024 18:35:49 +0200
Subject: [PATCH 21/43] Solve code review suggestions 2
---
.../App/File System/src/Account/FileAccountWizard.Page.al | 4 ++--
.../App/File System/src/FileSystem/FileSystem.Codeunit.al | 2 +-
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/src/System Application/App/File System/src/Account/FileAccountWizard.Page.al b/src/System Application/App/File System/src/Account/FileAccountWizard.Page.al
index 764d393f8c..c3a841ccd3 100644
--- a/src/System Application/App/File System/src/Account/FileAccountWizard.Page.al
+++ b/src/System Application/App/File System/src/Account/FileAccountWizard.Page.al
@@ -131,7 +131,7 @@ page 9451 "File Account Wizard"
Caption = ' ';
Editable = false;
Visible = ChooseConnectorVisible;
- ToolTip = 'Select the type of account you want to create.';
+ ToolTip = 'Specifies the type of the account you want to create.';
ShowCaption = false;
Width = 1;
}
@@ -243,7 +243,7 @@ page 9451 "File Account Wizard"
Editable = true;
Enabled = true;
Caption = 'Set as default';
- ToolTip = 'Use this account for all scenarios for which an account is not specified. Scenarios are processes that involve sending documents or notifications by file.';
+ ToolTip = 'Specifies the the account for all scenarios.';
}
}
}
diff --git a/src/System Application/App/File System/src/FileSystem/FileSystem.Codeunit.al b/src/System Application/App/File System/src/FileSystem/FileSystem.Codeunit.al
index 15b179c2c3..c6b9fc49fa 100644
--- a/src/System Application/App/File System/src/FileSystem/FileSystem.Codeunit.al
+++ b/src/System Application/App/File System/src/FileSystem/FileSystem.Codeunit.al
@@ -156,7 +156,7 @@ codeunit 9454 "File System"
/// Correctly combined path.
procedure CombinePath(Path: Text; ChildPath: Text): Text
begin
- Exit(FileSystemImpl.CombinePath(Path, ChildPath));
+ exit(FileSystemImpl.CombinePath(Path, ChildPath));
end;
///
From e0777675c96d1e88f945098c5967ae1618900e92 Mon Sep 17 00:00:00 2001
From: Thomas Williamson
Date: Fri, 23 Aug 2024 18:46:35 +0200
Subject: [PATCH 22/43] Use labels for telemetry
---
.../App/File System/src/Account/FileAccountWizard.Page.al | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/src/System Application/App/File System/src/Account/FileAccountWizard.Page.al b/src/System Application/App/File System/src/Account/FileAccountWizard.Page.al
index c3a841ccd3..da47ecc549 100644
--- a/src/System Application/App/File System/src/Account/FileAccountWizard.Page.al
+++ b/src/System Application/App/File System/src/Account/FileAccountWizard.Page.al
@@ -400,15 +400,17 @@ page 9451 "File Account Wizard"
FeatureTelemetry: Codeunit "Feature Telemetry";
AccountWasRegistered: Boolean;
ConnectorSucceeded: Boolean;
+ CTHTok: Label '%1 account has been setup.', Locked = true;
+ CTITok: Label '%1 account has failed to setup. Error: %2', Locked = true;
begin
ConnectorSucceeded := TryRegisterAccount(AccountWasRegistered);
if AccountWasRegistered then begin
FeatureTelemetry.LogUptake('0000CTF', 'File Access', Enum::"Feature Uptake Status"::"Set up");
- Session.LogMessage('0000CTH', Format(Rec.Connector) + ' account has been setup.', Verbosity::Normal, DataClassification::SystemMetadata, TelemetryScope::ExtensionPublisher, 'Category', FileCategoryLbl);
+ Session.LogMessage('0000CTH', StrSubstNo(CTHTok, Rec.Connector), Verbosity::Normal, DataClassification::SystemMetadata, TelemetryScope::ExtensionPublisher, 'Category', FileCategoryLbl);
NextStep(false);
end else begin
- Session.LogMessage('0000CTI', StrSubstNo(Format(Rec.Connector) + ' account has failed to setup. Error: %1', GetLastErrorCallStack()), Verbosity::Normal, DataClassification::SystemMetadata, TelemetryScope::ExtensionPublisher, 'Category', FileCategoryLbl);
+ Session.LogMessage('0000CTI', StrSubstNo(CTITok, Rec.Connector, GetLastErrorCallStack()), Verbosity::Normal, DataClassification::SystemMetadata, TelemetryScope::ExtensionPublisher, 'Category', FileCategoryLbl);
NextStep(true);
end;
From f1c251a34841e0aeb81068915ba81a5bf2d8f312 Mon Sep 17 00:00:00 2001
From: Thomas Williamson
Date: Mon, 26 Aug 2024 15:01:38 +0200
Subject: [PATCH 23/43] Fix code review suggestions
---
.../File System/src/Account/FileAccountWizard.Page.al | 11 +++++++----
...unit.al => FileSystemAccSelectionMock.Codeunit.al} | 0
.../Test/File System/src/FileAccountsTest.Codeunit.al | 1 -
3 files changed, 7 insertions(+), 5 deletions(-)
rename src/System Application/Test Library/File System/src/Mock/{FileAccountsSelectionMock.Codeunit.al => FileSystemAccSelectionMock.Codeunit.al} (100%)
diff --git a/src/System Application/App/File System/src/Account/FileAccountWizard.Page.al b/src/System Application/App/File System/src/Account/FileAccountWizard.Page.al
index da47ecc549..a5096fd906 100644
--- a/src/System Application/App/File System/src/Account/FileAccountWizard.Page.al
+++ b/src/System Application/App/File System/src/Account/FileAccountWizard.Page.al
@@ -398,19 +398,22 @@ page 9451 "File Account Wizard"
local procedure ShowRegisterAccountStep()
var
FeatureTelemetry: Codeunit "Feature Telemetry";
+ Telemetry: Codeunit Telemetry;
AccountWasRegistered: Boolean;
ConnectorSucceeded: Boolean;
- CTHTok: Label '%1 account has been setup.', Locked = true;
- CTITok: Label '%1 account has failed to setup. Error: %2', Locked = true;
+ CustomDimensions: Dictionary of [Text, Text];
+ CTHLbl: Label '%1 account has been setup.', Locked = true;
+ CTILbl: Label '%1 account has failed to setup. Error: %2', Locked = true;
begin
ConnectorSucceeded := TryRegisterAccount(AccountWasRegistered);
+ CustomDimensions.Add('Category', FileCategoryLbl);
if AccountWasRegistered then begin
FeatureTelemetry.LogUptake('0000CTF', 'File Access', Enum::"Feature Uptake Status"::"Set up");
- Session.LogMessage('0000CTH', StrSubstNo(CTHTok, Rec.Connector), Verbosity::Normal, DataClassification::SystemMetadata, TelemetryScope::ExtensionPublisher, 'Category', FileCategoryLbl);
+ Telemetry.LogMessage('0000CTH', StrSubstNo(CTHLbl, Rec.Connector), Verbosity::Normal, DataClassification::SystemMetadata, TelemetryScope::ExtensionPublisher, CustomDimensions);
NextStep(false);
end else begin
- Session.LogMessage('0000CTI', StrSubstNo(CTITok, Rec.Connector, GetLastErrorCallStack()), Verbosity::Normal, DataClassification::SystemMetadata, TelemetryScope::ExtensionPublisher, 'Category', FileCategoryLbl);
+ Telemetry.LogMessage('0000CTI', StrSubstNo(CTILbl, Rec.Connector, GetLastErrorCallStack()), Verbosity::Normal, DataClassification::SystemMetadata, TelemetryScope::ExtensionPublisher, CustomDimensions);
NextStep(true);
end;
diff --git a/src/System Application/Test Library/File System/src/Mock/FileAccountsSelectionMock.Codeunit.al b/src/System Application/Test Library/File System/src/Mock/FileSystemAccSelectionMock.Codeunit.al
similarity index 100%
rename from src/System Application/Test Library/File System/src/Mock/FileAccountsSelectionMock.Codeunit.al
rename to src/System Application/Test Library/File System/src/Mock/FileSystemAccSelectionMock.Codeunit.al
diff --git a/src/System Application/Test/File System/src/FileAccountsTest.Codeunit.al b/src/System Application/Test/File System/src/FileAccountsTest.Codeunit.al
index 7f4ae74727..cd111aea64 100644
--- a/src/System Application/Test/File System/src/FileAccountsTest.Codeunit.al
+++ b/src/System Application/Test/File System/src/FileAccountsTest.Codeunit.al
@@ -19,7 +19,6 @@ codeunit 134750 "File Accounts Test"
Assert: Codeunit "Library Assert";
PermissionsMock: Codeunit "Permissions Mock";
AccountToSelect: Guid;
- AccountNameLbl: Label '%1 (%2)', Locked = true;
[Test]
[Scope('OnPrem')]
From 73ed29231a679182cdebf5d6d7bf5fbf565cf6f6 Mon Sep 17 00:00:00 2001
From: Thomas Williamson
Date: Tue, 27 Aug 2024 14:35:51 +0200
Subject: [PATCH 24/43] Remove useless internal attributes
---
.../App/File System/src/Account/FileAccountImpl.Codeunit.al | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/src/System Application/App/File System/src/Account/FileAccountImpl.Codeunit.al b/src/System Application/App/File System/src/Account/FileAccountImpl.Codeunit.al
index 4568e3b9ab..c4341eae56 100644
--- a/src/System Application/App/File System/src/Account/FileAccountImpl.Codeunit.al
+++ b/src/System Application/App/File System/src/Account/FileAccountImpl.Codeunit.al
@@ -156,7 +156,7 @@ codeunit 9451 "File Account Impl."
exit(not FileAccount.IsEmpty());
end;
- internal procedure IsUserFileAdmin(): Boolean
+ procedure IsUserFileAdmin(): Boolean
var
FileScenario: Record "File Scenario";
begin
@@ -215,7 +215,7 @@ codeunit 9451 "File Account Impl."
FileAccountBrowser.Run();
end;
- internal procedure CheckPermissions()
+ procedure CheckPermissions()
begin
if not IsUserFileAdmin() then
Error(CannotManageSetupErr);
@@ -236,7 +236,7 @@ codeunit 9451 "File Account Impl."
end;
[InternalEvent(false)]
- internal procedure OnAfterSetSelectionFilter(var FileAccount: Record "File Account")
+ procedure OnAfterSetSelectionFilter(var FileAccount: Record "File Account")
begin
end;
From 017b7d0643520f212be73d51b9b0d371d8ec6e98 Mon Sep 17 00:00:00 2001
From: Thomas Williamson
Date: Fri, 30 Aug 2024 15:48:44 +0200
Subject: [PATCH 25/43] Refactored to media only
---
.../src/Account/FileAccount.Table.al | 7 ----
.../src/Account/FileAccountImpl.Codeunit.al | 32 ++++---------------
.../src/Account/FileAccounts.Page.al | 2 +-
.../Connector/FileSystemConnector.Table.al | 3 +-
4 files changed, 8 insertions(+), 36 deletions(-)
diff --git a/src/System Application/App/File System/src/Account/FileAccount.Table.al b/src/System Application/App/File System/src/Account/FileAccount.Table.al
index 6c07eb775b..5bd204545c 100644
--- a/src/System Application/App/File System/src/Account/FileAccount.Table.al
+++ b/src/System Application/App/File System/src/Account/FileAccount.Table.al
@@ -35,13 +35,6 @@ table 9450 "File Account"
Access = Internal;
DataClassification = SystemMetadata;
}
-
- field(6; LogoBlob; Blob)
- {
- Access = Internal;
- DataClassification = SystemMetadata;
- Subtype = Bitmap;
- }
}
keys
diff --git a/src/System Application/App/File System/src/Account/FileAccountImpl.Codeunit.al b/src/System Application/App/File System/src/Account/FileAccountImpl.Codeunit.al
index c4341eae56..7c45ca4bf7 100644
--- a/src/System Application/App/File System/src/Account/FileAccountImpl.Codeunit.al
+++ b/src/System Application/App/File System/src/Account/FileAccountImpl.Codeunit.al
@@ -36,10 +36,8 @@ codeunit 9451 "File Account Impl."
TempFileAccount := FileAccounts;
TempFileAccount.Connector := Connector;
- if LoadLogos then begin
+ if LoadLogos then
ImportLogo(TempFileAccount, Connector);
- ImportLogoBlob(TempFileAccount, Connector);
- end;
if not TempFileAccount.Insert() then;
until FileAccounts.Next() = 0;
@@ -140,11 +138,12 @@ codeunit 9451 "File Account Impl."
TempBlob.CreateOutStream(OutStream);
Base64Convert.FromBase64(ConnectorLogoBase64, OutStream);
TempBlob.CreateInStream(InStream);
+ FileConnectorLogo.Init();
FileConnectorLogo.Connector := FileAccount.Connector;
FileConnectorLogo.Logo.ImportStream(InStream, StrSubstNo(ConnectorLogoDescriptionTxt, FileAccount.Connector));
if FileConnectorLogo.Insert() then;
end;
- FileAccount.Logo := FileConnectorLogo.Logo
+ FileAccount.Logo := FileConnectorLogo.Logo;
end;
procedure IsAnyAccountRegistered(): Boolean
@@ -165,21 +164,16 @@ codeunit 9451 "File Account Impl."
procedure FindAllConnectors(var FileConnector: Record "File System Connector")
var
- Base64Convert: Codeunit "Base64 Convert";
+ FileConnectorLogo: Record "File System Connector Logo";
ConnectorInterface: Interface "File System Connector";
FileSystemConnector: Enum "File System Connector";
- ConnectorLogoBase64: Text;
- OutStream: Outstream;
begin
foreach FileSystemConnector in Enum::"File System Connector".Ordinals() do begin
ConnectorInterface := FileSystemConnector;
- ConnectorLogoBase64 := ConnectorInterface.GetLogoAsBase64();
FileConnector.Connector := FileSystemConnector;
FileConnector.Description := ConnectorInterface.GetDescription();
- if ConnectorLogoBase64 <> '' then begin
- FileConnector.Logo.CreateOutStream(OutStream);
- Base64Convert.FromBase64(ConnectorLogoBase64, OutStream);
- end;
+ if FileConnectorLogo.Get(FileConnector.Connector) then
+ FileConnector.Logo := FileConnectorLogo.Logo;
FileConnector.Insert();
end;
end;
@@ -221,20 +215,6 @@ codeunit 9451 "File Account Impl."
Error(CannotManageSetupErr);
end;
- local procedure ImportLogoBlob(var FileAccount: Record "File Account"; FileSystemConnector: Interface "File System Connector")
- var
- Base64Convert: Codeunit "Base64 Convert";
- ConnectorLogoBase64: Text;
- OutStream: Outstream;
- begin
- ConnectorLogoBase64 := FileSystemConnector.GetLogoAsBase64();
-
- if ConnectorLogoBase64 <> '' then begin
- FileAccount.LogoBlob.CreateOutStream(OutStream);
- Base64Convert.FromBase64(ConnectorLogoBase64, OutStream);
- end;
- end;
-
[InternalEvent(false)]
procedure OnAfterSetSelectionFilter(var FileAccount: Record "File Account")
begin
diff --git a/src/System Application/App/File System/src/Account/FileAccounts.Page.al b/src/System Application/App/File System/src/Account/FileAccounts.Page.al
index 02cc4a7fc0..1c2d4a397f 100644
--- a/src/System Application/App/File System/src/Account/FileAccounts.Page.al
+++ b/src/System Application/App/File System/src/Account/FileAccounts.Page.al
@@ -36,7 +36,7 @@ page 9450 "File Accounts"
{
Visible = ShowLogo;
FreezeColumn = NameField;
- field(LogoField; Rec.LogoBlob)
+ field(LogoField; Rec.Logo)
{
ShowCaption = false;
Caption = ' ';
diff --git a/src/System Application/App/File System/src/Connector/FileSystemConnector.Table.al b/src/System Application/App/File System/src/Connector/FileSystemConnector.Table.al
index b92c87e5e9..1de21c827c 100644
--- a/src/System Application/App/File System/src/Connector/FileSystemConnector.Table.al
+++ b/src/System Application/App/File System/src/Connector/FileSystemConnector.Table.al
@@ -18,10 +18,9 @@ table 9451 "File System Connector"
{
DataClassification = SystemMetadata;
}
- field(2; Logo; Blob)
+ field(2; Logo; Media)
{
DataClassification = SystemMetadata;
- Subtype = Bitmap;
}
field(3; Description; Text[250])
{
From 4e5968ef378deec3eb3143a0caa1c7d42cd3af59 Mon Sep 17 00:00:00 2001
From: Thomas Williamson
Date: Tue, 17 Sep 2024 14:52:53 +0200
Subject: [PATCH 26/43] Fix tooltips
---
.../App/File System/src/Scenario/FileScenariosFactBox.Page.al | 2 +-
.../File System/src/Scenario/FileScenariosForAccount.Page.al | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/System Application/App/File System/src/Scenario/FileScenariosFactBox.Page.al b/src/System Application/App/File System/src/Scenario/FileScenariosFactBox.Page.al
index ede1aaf0fd..a01b690d42 100644
--- a/src/System Application/App/File System/src/Scenario/FileScenariosFactBox.Page.al
+++ b/src/System Application/App/File System/src/Scenario/FileScenariosFactBox.Page.al
@@ -32,7 +32,7 @@ page 9453 "File Scenarios FactBox"
{
field(Name; Format(Rec.Scenario))
{
- ToolTip = 'The file scenario.';
+ ToolTip = 'Specifies the name of the file scenario.';
Caption = 'File scenario';
Editable = false;
}
diff --git a/src/System Application/App/File System/src/Scenario/FileScenariosForAccount.Page.al b/src/System Application/App/File System/src/Scenario/FileScenariosForAccount.Page.al
index 4f07b155b4..53dfcaf231 100644
--- a/src/System Application/App/File System/src/Scenario/FileScenariosForAccount.Page.al
+++ b/src/System Application/App/File System/src/Scenario/FileScenariosForAccount.Page.al
@@ -32,7 +32,7 @@ page 9454 "File Scenarios for Account"
{
field(Name; Rec."Display Name")
{
- ToolTip = 'The file scenario.';
+ ToolTip = 'Specifies the name of the file scenario.';
Caption = 'File scenario';
Editable = false;
}
From 5fd8fc88506c04bc7bcf6b0e1b6dee645e9d2fdf Mon Sep 17 00:00:00 2001
From: Thomas Williamson
Date: Tue, 17 Sep 2024 14:55:31 +0200
Subject: [PATCH 27/43] Revert GetIsLegacyActionBarEnabled change
---
.../App/User Settings/src/UserSettingsImpl.Codeunit.al | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/System Application/App/User Settings/src/UserSettingsImpl.Codeunit.al b/src/System Application/App/User Settings/src/UserSettingsImpl.Codeunit.al
index 3e5453c1a8..03d8505e1d 100644
--- a/src/System Application/App/User Settings/src/UserSettingsImpl.Codeunit.al
+++ b/src/System Application/App/User Settings/src/UserSettingsImpl.Codeunit.al
@@ -541,7 +541,7 @@ codeunit 9175 "User Settings Impl."
end;
end;
- //[EventSubscriber(ObjectType::Codeunit, Codeunit::"System Action Triggers", 'GetIsLegacyActionBarEnabled', '', false, false)]
+ [EventSubscriber(ObjectType::Codeunit, Codeunit::"System Action Triggers", 'GetIsLegacyActionBarEnabled', '', false, false)]
local procedure GetIsLegacyActionBarEnabled(var IsEnabled: Boolean)
begin
IsEnabled := IsLegacyActionBarEnabled(UserSecurityId());
From ecf81b5f1e797b8f3b517fb01f126c07e9f0c51c Mon Sep 17 00:00:00 2001
From: Thomas Williamson
Date: Thu, 19 Sep 2024 09:17:12 +0200
Subject: [PATCH 28/43] Renumber Test Lib
---
.../File System/Permissions/FileSystemAdmin.PermissionSet.al | 2 +-
.../File System/Permissions/FileSystemEdit.PermissionSet.al | 2 +-
src/System Application/Test Library/File System/app.json | 4 ++--
.../File System/src/FileSystemTestLib.Codeunit.al | 2 +-
.../File System/src/Mock/FileConnectorMock.Codeunit.al | 2 +-
.../File System/src/Mock/FileScenarioMock.Codeunit.al | 2 +-
.../src/Mock/FileSystemAccSelectionMock.Codeunit.al | 2 +-
.../Test Library/File System/src/TestFileAccount.Table.al | 2 +-
.../File System/src/TestFileConnectorSetup.Table.al | 2 +-
.../Test Library/File System/src/TestFileScenario.EnumExt.al | 4 ++--
.../File System/src/TestFileSystemConnector.Codeunit.al | 2 +-
.../File System/src/TestFileSystemConnector.EnumExt.al | 4 ++--
12 files changed, 15 insertions(+), 15 deletions(-)
diff --git a/src/System Application/Test Library/File System/Permissions/FileSystemAdmin.PermissionSet.al b/src/System Application/Test Library/File System/Permissions/FileSystemAdmin.PermissionSet.al
index 8888e89d7b..ef304facff 100644
--- a/src/System Application/Test Library/File System/Permissions/FileSystemAdmin.PermissionSet.al
+++ b/src/System Application/Test Library/File System/Permissions/FileSystemAdmin.PermissionSet.al
@@ -7,7 +7,7 @@ namespace System.TestLibraries.FileSystem;
using System.FileSystem;
-permissionset 80200 "File System Admin"
+permissionset 135810 "File System Admin"
{
Assignable = true;
IncludedPermissionSets = "File System - Admin";
diff --git a/src/System Application/Test Library/File System/Permissions/FileSystemEdit.PermissionSet.al b/src/System Application/Test Library/File System/Permissions/FileSystemEdit.PermissionSet.al
index eaea59bcff..41cfad6fe2 100644
--- a/src/System Application/Test Library/File System/Permissions/FileSystemEdit.PermissionSet.al
+++ b/src/System Application/Test Library/File System/Permissions/FileSystemEdit.PermissionSet.al
@@ -8,7 +8,7 @@ namespace System.TestLibraries.FileSystem;
using System.FileSystem;
using System.Environment;
-permissionset 80201 "File System Edit"
+permissionset 135811 "File System Edit"
{
Assignable = true;
IncludedPermissionSets = "File System - Edit";
diff --git a/src/System Application/Test Library/File System/app.json b/src/System Application/Test Library/File System/app.json
index f2611db303..d713f0c1bb 100644
--- a/src/System Application/Test Library/File System/app.json
+++ b/src/System Application/Test Library/File System/app.json
@@ -30,8 +30,8 @@
"platform": "24.0.0.0",
"idRanges": [
{
- "from": 80200,
- "to": 800299
+ "from": 135810,
+ "to": 135819
}
],
"contextSensitiveHelpUrl": "https://go.microsoft.com/fwlink/?linkid=2134520",
diff --git a/src/System Application/Test Library/File System/src/FileSystemTestLib.Codeunit.al b/src/System Application/Test Library/File System/src/FileSystemTestLib.Codeunit.al
index f168e94716..f21769e21b 100644
--- a/src/System Application/Test Library/File System/src/FileSystemTestLib.Codeunit.al
+++ b/src/System Application/Test Library/File System/src/FileSystemTestLib.Codeunit.al
@@ -7,7 +7,7 @@ namespace System.TestLibraries.FileSystem;
using System.FileSystem;
-codeunit 80204 "File System Test Lib."
+codeunit 135813 "File System Test Lib."
{
Permissions = tabledata "File Scenario" = rid;
diff --git a/src/System Application/Test Library/File System/src/Mock/FileConnectorMock.Codeunit.al b/src/System Application/Test Library/File System/src/Mock/FileConnectorMock.Codeunit.al
index fcba1bb905..2a41d93300 100644
--- a/src/System Application/Test Library/File System/src/Mock/FileConnectorMock.Codeunit.al
+++ b/src/System Application/Test Library/File System/src/Mock/FileConnectorMock.Codeunit.al
@@ -8,7 +8,7 @@ namespace System.TestLibraries.FileSystem;
using System.FileSystem;
using System.TestLibraries.Utilities;
-codeunit 134760 "File Connector Mock"
+codeunit 135810 "File Connector Mock"
{
var
Any: Codeunit Any;
diff --git a/src/System Application/Test Library/File System/src/Mock/FileScenarioMock.Codeunit.al b/src/System Application/Test Library/File System/src/Mock/FileScenarioMock.Codeunit.al
index 51a0e32d63..8a29e86b79 100644
--- a/src/System Application/Test Library/File System/src/Mock/FileScenarioMock.Codeunit.al
+++ b/src/System Application/Test Library/File System/src/Mock/FileScenarioMock.Codeunit.al
@@ -7,7 +7,7 @@ namespace System.TestLibraries.FileSystem;
using System.FileSystem;
-codeunit 134761 "File Scenario Mock"
+codeunit 135811 "File Scenario Mock"
{
Permissions = tabledata "File Scenario" = rid;
diff --git a/src/System Application/Test Library/File System/src/Mock/FileSystemAccSelectionMock.Codeunit.al b/src/System Application/Test Library/File System/src/Mock/FileSystemAccSelectionMock.Codeunit.al
index 847045e11a..08ed37ef9c 100644
--- a/src/System Application/Test Library/File System/src/Mock/FileSystemAccSelectionMock.Codeunit.al
+++ b/src/System Application/Test Library/File System/src/Mock/FileSystemAccSelectionMock.Codeunit.al
@@ -10,7 +10,7 @@ using System.FileSystem;
///
/// Used to mock selected file accounts on File Accounts page.
///
-codeunit 134762 "File System Acc Selection Mock"
+codeunit 135812 "File System Acc Selection Mock"
{
EventSubscriberInstance = Manual;
diff --git a/src/System Application/Test Library/File System/src/TestFileAccount.Table.al b/src/System Application/Test Library/File System/src/TestFileAccount.Table.al
index c7cb6c0898..a6734c7a76 100644
--- a/src/System Application/Test Library/File System/src/TestFileAccount.Table.al
+++ b/src/System Application/Test Library/File System/src/TestFileAccount.Table.al
@@ -5,7 +5,7 @@
namespace System.TestLibraries.FileSystem;
-table 80200 "Test File Account"
+table 135810 "Test File Account"
{
DataClassification = SystemMetadata;
ReplicateData = false;
diff --git a/src/System Application/Test Library/File System/src/TestFileConnectorSetup.Table.al b/src/System Application/Test Library/File System/src/TestFileConnectorSetup.Table.al
index f5791e5917..edf6e6ae24 100644
--- a/src/System Application/Test Library/File System/src/TestFileConnectorSetup.Table.al
+++ b/src/System Application/Test Library/File System/src/TestFileConnectorSetup.Table.al
@@ -5,7 +5,7 @@
namespace System.TestLibraries.FileSystem;
-table 80201 "Test File Connector Setup"
+table 135811 "Test File Connector Setup"
{
DataClassification = SystemMetadata;
ReplicateData = false;
diff --git a/src/System Application/Test Library/File System/src/TestFileScenario.EnumExt.al b/src/System Application/Test Library/File System/src/TestFileScenario.EnumExt.al
index b62b61a743..ecd868e9d7 100644
--- a/src/System Application/Test Library/File System/src/TestFileScenario.EnumExt.al
+++ b/src/System Application/Test Library/File System/src/TestFileScenario.EnumExt.al
@@ -7,9 +7,9 @@ namespace System.TestLibraries.FileSystem;
using System.FileSystem;
-enumextension 80200 "Test File Scenario" extends "File Scenario"
+enumextension 135810 "Test File Scenario" extends "File Scenario"
{
- value(80200; "Test File Scenario")
+ value(135810; "Test File Scenario")
{
}
}
\ No newline at end of file
diff --git a/src/System Application/Test Library/File System/src/TestFileSystemConnector.Codeunit.al b/src/System Application/Test Library/File System/src/TestFileSystemConnector.Codeunit.al
index c4ae847d2d..13fb9e282a 100644
--- a/src/System Application/Test Library/File System/src/TestFileSystemConnector.Codeunit.al
+++ b/src/System Application/Test Library/File System/src/TestFileSystemConnector.Codeunit.al
@@ -7,7 +7,7 @@ namespace System.TestLibraries.FileSystem;
using System.FileSystem;
-codeunit 80202 "Test File System Connector" implements "File System Connector"
+codeunit 135814 "Test File System Connector" implements "File System Connector"
{
procedure ListFiles(AccountId: Guid; Path: Text; FilePaginationData: Codeunit "File Pagination Data"; var FileAccountContent: Record "File Account Content" temporary);
begin
diff --git a/src/System Application/Test Library/File System/src/TestFileSystemConnector.EnumExt.al b/src/System Application/Test Library/File System/src/TestFileSystemConnector.EnumExt.al
index 62e25b5415..bc58e63b3a 100644
--- a/src/System Application/Test Library/File System/src/TestFileSystemConnector.EnumExt.al
+++ b/src/System Application/Test Library/File System/src/TestFileSystemConnector.EnumExt.al
@@ -7,9 +7,9 @@ namespace System.TestLibraries.FileSystem;
using System.FileSystem;
-enumextension 80201 "Test File System Connector" extends "File System Connector"
+enumextension 135815 "Test File System Connector" extends "File System Connector"
{
- value(80200; "Test File System Connector")
+ value(135810; "Test File System Connector")
{
Implementation = "File System Connector" = "Test File System Connector";
}
From 07461461eb77044916ae6c87c45ac8bcc8975e94 Mon Sep 17 00:00:00 2001
From: Thomas Williamson
Date: Fri, 15 Nov 2024 11:41:16 +0100
Subject: [PATCH 29/43] Bump version and platform to 26.0.0.0 in app.json files
---
src/System Application/App/app.json | 4 ++--
src/System Application/Test Library/app.json | 8 ++++----
src/System Application/Test/app.json | 16 ++++++++--------
3 files changed, 14 insertions(+), 14 deletions(-)
diff --git a/src/System Application/App/app.json b/src/System Application/App/app.json
index ad829f3748..f2c345ebb3 100644
--- a/src/System Application/App/app.json
+++ b/src/System Application/App/app.json
@@ -4,7 +4,7 @@
"publisher": "Microsoft",
"brief": "Provides a standard set of capabilities that serve as a foundation for developing business apps.",
"description": "Contains an expansive set of open source modules that make it easier to build, maintain, and easily upgrade on-premises and online apps. These modules let you focus on the business logic, and the needs of your users or customers.",
- "version": "25.0.0.0",
+ "version": "26.0.0.0",
"privacyStatement": "https://go.microsoft.com/fwlink/?linkid=724009",
"EULA": "https://go.microsoft.com/fwlink/?linkid=2009120",
"help": "https://go.microsoft.com/fwlink/?linkid=2103698",
@@ -28,7 +28,7 @@
"screenshots": [
],
- "platform": "24.0.0.0",
+ "platform": "26.0.0.0",
"target": "OnPrem",
"idRanges": [
{
diff --git a/src/System Application/Test Library/app.json b/src/System Application/Test Library/app.json
index c9e3a6b8f3..eaffc6b90a 100644
--- a/src/System Application/Test Library/app.json
+++ b/src/System Application/Test Library/app.json
@@ -4,7 +4,7 @@
"publisher": "Microsoft",
"brief": "Test libraries that provide basic test setup for the System Application tests.",
"description": "Contains an expansive set of library methods to be used exclusively in tests.",
- "version": "25.0.0.0",
+ "version": "26.0.0.0",
"privacyStatement": "https://go.microsoft.com/fwlink/?LinkId=724009",
"EULA": "https://go.microsoft.com/fwlink/?linkid=2009120",
"help": "https://go.microsoft.com/fwlink/?linkid=2131960",
@@ -16,13 +16,13 @@
"id": "63ca2fa4-4f03-4f2b-a480-172fef340d3f",
"name": "System Application",
"publisher": "Microsoft",
- "version": "25.0.0.0"
+ "version": "26.0.0.0"
},
{
"id": "e7320ebb-08b3-4406-b1ec-b4927d3e280b",
"name": "Any",
"publisher": "Microsoft",
- "version": "25.0.0.0"
+ "version": "26.0.0.0"
}
],
"screenshots": [
@@ -37,7 +37,7 @@
"allowDownloadingSource": true,
"includeSourceInSymbolFile": true
},
- "platform": "24.0.0.0",
+ "platform": "26.0.0.0",
"target": "OnPrem",
"idRanges": [
{
diff --git a/src/System Application/Test/app.json b/src/System Application/Test/app.json
index 5965bc735a..59b36f860b 100644
--- a/src/System Application/Test/app.json
+++ b/src/System Application/Test/app.json
@@ -4,7 +4,7 @@
"publisher": "Microsoft",
"brief": "Test suite for the System Application.",
"description": "Contains an expansive set tests for the System Application.",
- "version": "25.0.0.0",
+ "version": "26.0.0.0",
"privacyStatement": "https://go.microsoft.com/fwlink/?LinkId=724009",
"EULA": "https://go.microsoft.com/fwlink/?linkid=2009120",
"help": "https://go.microsoft.com/fwlink/?linkid=2131960",
@@ -16,43 +16,43 @@
"id": "63ca2fa4-4f03-4f2b-a480-172fef340d3f",
"name": "System Application",
"publisher": "Microsoft",
- "version": "25.0.0.0"
+ "version": "26.0.0.0"
},
{
"id": "9856ae4f-d1a7-46ef-89bb-6ef056398228",
"name": "System Application Test Library",
"publisher": "Microsoft",
- "version": "25.0.0.0"
+ "version": "26.0.0.0"
},
{
"id": "dd0be2ea-f733-4d65-bb34-a28f4624fb14",
"name": "Library Assert",
"publisher": "Microsoft",
- "version": "25.0.0.0"
+ "version": "26.0.0.0"
},
{
"id": "e7320ebb-08b3-4406-b1ec-b4927d3e280b",
"name": "Any",
"publisher": "Microsoft",
- "version": "25.0.0.0"
+ "version": "26.0.0.0"
},
{
"id": "5095f467-0a01-4b99-99d1-9ff1237d286f",
"name": "Library Variable Storage",
"publisher": "Microsoft",
- "version": "25.0.0.0"
+ "version": "26.0.0.0"
},
{
"id": "40860557-a18d-42ad-aecb-22b7dd80dc80",
"name": "Permissions Mock",
"publisher": "Microsoft",
- "version": "25.0.0.0"
+ "version": "26.0.0.0"
}
],
"screenshots": [
],
- "platform": "24.0.0.0",
+ "platform": "26.0.0.0",
"features": [
"GenerateCaptions",
"TranslationFile"
From ca63fcfe69b7d87f7738f15f7765158573bb9581 Mon Sep 17 00:00:00 2001
From: Thomas Williamson
Date: Fri, 15 Nov 2024 11:45:13 +0100
Subject: [PATCH 30/43] Bump version and platform to 26.0.0.0 in app.json
---
src/System Application/App/File System/app.json | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/src/System Application/App/File System/app.json b/src/System Application/App/File System/app.json
index 8454264f45..0a45dc0288 100644
--- a/src/System Application/App/File System/app.json
+++ b/src/System Application/App/File System/app.json
@@ -4,7 +4,7 @@
"publisher": "Microsoft",
"brief": "Enables access to external file systems from Business Central.",
"description": "Enables access to external file systems from Business Central.",
- "version": "25.0.0.0",
+ "version": "26.0.0.0",
"privacyStatement": "https://go.microsoft.com/fwlink/?linkid=724009",
"EULA": "https://go.microsoft.com/fwlink/?linkid=2009120",
"help": "https://go.microsoft.com/fwlink/?linkid=2103698",
@@ -15,37 +15,37 @@
"id": "7e3b999e-1182-45d2-8b82-d5127ddba9b2",
"name": "DotNet Aliases",
"publisher": "Microsoft",
- "version": "25.0.0.0"
+ "version": "26.0.0.0"
},
{
"id": "872fe7e8-9893-40ae-ab94-c123ed30fdbd",
"name": "Extension Management",
"publisher": "Microsoft",
- "version": "25.0.0.0"
+ "version": "26.0.0.0"
},
{
"id": "de35f591-7216-4e60-8be1-1911d71a7fc2",
"name": "Telemetry",
"publisher": "Microsoft",
- "version": "25.0.0.0"
+ "version": "26.0.0.0"
},
{
"id": "0846d207-5dec-4c1b-afd8-6a25e1e14b9d",
"name": "Base64 Convert",
"publisher": "Microsoft",
- "version": "25.0.0.0"
+ "version": "26.0.0.0"
},
{
"id": "a4584a53-9345-458a-af20-d1df2fab7bd8",
"name": "Confirm Management",
"publisher": "Microsoft",
- "version": "25.0.0.0"
+ "version": "26.0.0.0"
},
{
"id": "e31ad830-3d46-472e-afeb-1d3d35247943",
"name": "BLOB Storage",
"publisher": "Microsoft",
- "version": "25.0.0.0"
+ "version": "26.0.0.0"
}
],
"internalsVisibleTo": [
@@ -58,7 +58,7 @@
"screenshots": [
],
- "platform": "24.0.0.0",
+ "platform": "26.0.0.0",
"idRanges": [
{
"from": 9450,
From c3f3b99ed129c3fecbea7c9730bee49a88919331 Mon Sep 17 00:00:00 2001
From: Thomas Williamson
Date: Fri, 15 Nov 2024 16:16:01 +0100
Subject: [PATCH 31/43] Bump version and platform to 26.0.0.0 in app.json for
File System module
---
.../Test Library/File System/app.json | 8 ++++----
.../Test/File System/app.json | 20 +++++++++----------
2 files changed, 14 insertions(+), 14 deletions(-)
diff --git a/src/System Application/Test Library/File System/app.json b/src/System Application/Test Library/File System/app.json
index d713f0c1bb..7c313c3a72 100644
--- a/src/System Application/Test Library/File System/app.json
+++ b/src/System Application/Test Library/File System/app.json
@@ -4,7 +4,7 @@
"publisher": "Microsoft",
"brief": "Test library for the File System module",
"description": "Test library for the File System module",
- "version": "25.0.0.0",
+ "version": "26.0.0.0",
"privacyStatement": "https://go.microsoft.com/fwlink/?linkid=724009",
"EULA": "https://go.microsoft.com/fwlink/?linkid=2009120",
"help": "https://go.microsoft.com/fwlink/?linkid=2103698",
@@ -15,19 +15,19 @@
"id": "c9c54414-80c3-4cc9-98c6-589158882774",
"name": "File System",
"publisher": "Microsoft",
- "version": "25.0.0.0"
+ "version": "26.0.0.0"
},
{
"id": "e7320ebb-08b3-4406-b1ec-b4927d3e280b",
"name": "Any",
"publisher": "Microsoft",
- "version": "24.0.0.0"
+ "version": "26.0.0.0"
}
],
"screenshots": [
],
- "platform": "24.0.0.0",
+ "platform": "26.0.0.0",
"idRanges": [
{
"from": 135810,
diff --git a/src/System Application/Test/File System/app.json b/src/System Application/Test/File System/app.json
index 25ca656ac3..044bf8efee 100644
--- a/src/System Application/Test/File System/app.json
+++ b/src/System Application/Test/File System/app.json
@@ -4,7 +4,7 @@
"publisher": "Microsoft",
"brief": "Tests for the File System module",
"description": "Tests for the File System module",
- "version": "25.0.0.0",
+ "version": "26.0.0.0",
"privacyStatement": "https://go.microsoft.com/fwlink/?linkid=724009",
"EULA": "https://go.microsoft.com/fwlink/?linkid=2009120",
"help": "https://go.microsoft.com/fwlink/?linkid=2103698",
@@ -15,55 +15,55 @@
"id": "c9c54414-80c3-4cc9-98c6-589158882774",
"name": "File System",
"publisher": "Microsoft",
- "version": "25.0.0.0"
+ "version": "26.0.0.0"
},
{
"id": "f188754b-3ffb-443a-9507-f5fbdae3af2c",
"name": "File System Test Library",
"publisher": "Microsoft",
- "version": "24.0.0.0"
+ "version": "26.0.0.0"
},
{
"id": "5095f467-0a01-4b99-99d1-9ff1237d286f",
"name": "Library Variable Storage",
"publisher": "Microsoft",
- "version": "24.0.0.0"
+ "version": "26.0.0.0"
},
{
"id": "e31ad830-3d46-472e-afeb-1d3d35247943",
"name": "BLOB Storage",
"publisher": "Microsoft",
- "version": "25.0.0.0"
+ "version": "26.0.0.0"
},
{
"id": "0846d207-5dec-4c1b-afd8-6a25e1e14b9d",
"name": "Base64 Convert",
"publisher": "Microsoft",
- "version": "25.0.0.0"
+ "version": "26.0.0.0"
},
{
"id": "dd0be2ea-f733-4d65-bb34-a28f4624fb14",
"name": "Library Assert",
"publisher": "Microsoft",
- "version": "24.0.0.0"
+ "version": "26.0.0.0"
},
{
"id": "e7320ebb-08b3-4406-b1ec-b4927d3e280b",
"name": "Any",
"publisher": "Microsoft",
- "version": "24.0.0.0"
+ "version": "26.0.0.0"
},
{
"id": "40860557-a18d-42ad-aecb-22b7dd80dc80",
"name": "Permissions Mock",
"publisher": "Microsoft",
- "version": "24.0.0.0"
+ "version": "26.0.0.0"
}
],
"screenshots": [
],
- "platform": "24.0.0.0",
+ "platform": "26.0.0.0",
"idRanges": [
{
"from": 134487,
From 63452f11646849ee808e022f8750a6bb4b921d33 Mon Sep 17 00:00:00 2001
From: Stefan Sosic
Date: Sat, 16 Nov 2024 16:27:52 +0100
Subject: [PATCH 32/43] Small Fixes
---
.../src/Account/FileAccount.Table.al | 6 ------
.../src/Account/FileAccountImpl.Codeunit.al | 10 +++++-----
.../src/Account/FileAccountWizard.Page.al | 17 +----------------
.../src/Account/FileAccounts.Page.al | 17 ++++-------------
.../Connector/FileSystemConnector.Interface.al | 2 --
.../Connector/FileSystemConnectorLogo.Table.al | 1 -
.../src/FileSystem/FileSystemImpl.Codeunit.al | 3 +--
.../src/Lookup/FileAccountBrowser.Page.al | 2 +-
.../Lookup/FileAccountBrowserMgt.Codeunit.al | 4 ++--
.../Lookup/FilePaginationDataImpl.Codeunit.al | 2 +-
.../src/Lookup/FolderNameInput.Page.al | 2 +-
.../src/Scenario/FileAccountScenario.Table.al | 9 ---------
.../src/Scenario/FileScenario.Table.al | 2 --
.../src/Scenario/FileScenarioImpl.Codeunit.al | 14 +++++++-------
.../src/Scenario/FileScenarioSetup.Page.al | 5 -----
15 files changed, 23 insertions(+), 73 deletions(-)
diff --git a/src/System Application/App/File System/src/Account/FileAccount.Table.al b/src/System Application/App/File System/src/Account/FileAccount.Table.al
index 5bd204545c..97803e2be2 100644
--- a/src/System Application/App/File System/src/Account/FileAccount.Table.al
+++ b/src/System Application/App/File System/src/Account/FileAccount.Table.al
@@ -19,17 +19,14 @@ table 9450 "File Account"
{
DataClassification = SystemMetadata;
}
-
field(2; Name; Text[250])
{
DataClassification = SystemMetadata; // Field only in Memory
}
-
field(4; Connector; Enum "File System Connector")
{
DataClassification = SystemMetadata;
}
-
field(5; Logo; Media)
{
Access = Internal;
@@ -43,7 +40,6 @@ table 9450 "File Account"
{
Clustered = true;
}
-
key(Name; Name)
{
Description = 'Used for sorting';
@@ -54,8 +50,6 @@ table 9450 "File Account"
{
fieldgroup(Brick; Logo, Name)
{
-
}
}
-
}
\ No newline at end of file
diff --git a/src/System Application/App/File System/src/Account/FileAccountImpl.Codeunit.al b/src/System Application/App/File System/src/Account/FileAccountImpl.Codeunit.al
index 7c45ca4bf7..d9580a3d53 100644
--- a/src/System Application/App/File System/src/Account/FileAccountImpl.Codeunit.al
+++ b/src/System Application/App/File System/src/Account/FileAccountImpl.Codeunit.al
@@ -123,12 +123,12 @@ codeunit 9451 "File Account Impl."
local procedure ImportLogo(var FileAccount: Record "File Account"; Connector: Interface "File System Connector")
var
FileConnectorLogo: Record "File System Connector Logo";
- TempBlob: Codeunit "Temp Blob";
Base64Convert: Codeunit "Base64 Convert";
- ConnectorLogoBase64: Text;
- OutStream: Outstream;
+ TempBlob: Codeunit "Temp Blob";
InStream: InStream;
ConnectorLogoDescriptionTxt: Label '%1 Logo', Locked = true;
+ OutStream: OutStream;
+ ConnectorLogoBase64: Text;
begin
ConnectorLogoBase64 := Connector.GetLogoAsBase64();
@@ -221,7 +221,7 @@ codeunit 9451 "File Account Impl."
end;
var
- ConfirmDeleteQst: Label 'Go ahead and delete?';
- ChooseNewDefaultTxt: Label 'Choose a Default Account';
CannotManageSetupErr: Label 'Your user account does not give you permission to set up file. Please contact your administrator.';
+ ChooseNewDefaultTxt: Label 'Choose a Default Account';
+ ConfirmDeleteQst: Label 'Go ahead and delete?';
}
\ No newline at end of file
diff --git a/src/System Application/App/File System/src/Account/FileAccountWizard.Page.al b/src/System Application/App/File System/src/Account/FileAccountWizard.Page.al
index a5096fd906..4ca67643cf 100644
--- a/src/System Application/App/File System/src/Account/FileAccountWizard.Page.al
+++ b/src/System Application/App/File System/src/Account/FileAccountWizard.Page.al
@@ -35,7 +35,6 @@ page 9451 "File Account Wizard"
{
area(Content)
{
-
group(Done)
{
Editable = false;
@@ -73,7 +72,6 @@ page 9451 "File Account Wizard"
Caption = 'Welcome to file in Business Central';
InstructionalText = 'Make file communications easier by connecting file accounts to Business Central. For example, store sales quotes and orders pdfs without opening an file app.';
}
-
field(LearnMoreHeader; LearnMoreTok)
{
Editable = false;
@@ -86,13 +84,11 @@ page 9451 "File Account Wizard"
Hyperlink(LearnMoreURLTxt);
end;
}
-
group(Privacy)
{
Caption = 'Privacy notice';
InstructionalText = 'By adding an file account you acknowledge that the file provider might be able to access the data you send in files from Business Central.';
}
-
group(GetStartedText)
{
Caption = 'Let''s go!';
@@ -118,7 +114,6 @@ page 9451 "File Account Wizard"
{
Caption = 'Specify the type of file account to add';
}
-
repeater(Connectors)
{
ShowCaption = false;
@@ -135,14 +130,12 @@ page 9451 "File Account Wizard"
ShowCaption = false;
Width = 1;
}
-
field(Name; Rec.Connector)
{
Caption = 'Account Type';
ToolTip = 'Specifies the type of the account you want to create.';
Editable = false;
}
-
field(Details; Rec.Description)
{
Caption = 'Details';
@@ -160,12 +153,10 @@ page 9451 "File Account Wizard"
{
Caption = 'There are no file apps available. To use this feature you must install an file app.';
}
-
label(NoConnectorsAvailable2)
{
Caption = 'File apps are available in Extension Management and AppSource.';
}
-
field(ExtensionManagement; ExtensionManagementTok)
{
Editable = false;
@@ -178,7 +169,6 @@ page 9451 "File Account Wizard"
Page.Run(Page::"Extension Management");
end;
}
-
field(AppSource; AppSourceTok)
{
Editable = false;
@@ -193,12 +183,10 @@ page 9451 "File Account Wizard"
AppSource.ShowAppSource();
end;
}
-
label(NoConnectorsAvailable3)
{
Caption = 'View a list of the available file apps';
}
-
field(LearnMore; LearnMoreTok)
{
Editable = false;
@@ -222,7 +210,6 @@ page 9451 "File Account Wizard"
Caption = 'Congratulations!';
InstructionalText = 'You have successfully added the file account. To check that it is working, send a test file.';
}
-
group(Account)
{
Caption = 'Account';
@@ -233,7 +220,6 @@ page 9451 "File Account Wizard"
ToolTip = 'Specifies the name of the account registered.';
}
}
-
group(Default)
{
Caption = '';
@@ -254,7 +240,6 @@ page 9451 "File Account Wizard"
{
area(Processing)
{
-
action(Cancel)
{
Visible = CancelActionVisible;
@@ -376,7 +361,7 @@ page 9451 "File Account Wizard"
ShowChooseConnectorStep();
Step::"Register Account":
ShowRegisterAccountStep();
- Step::"Done":
+ Step::Done:
ShowDoneStep();
end;
end;
diff --git a/src/System Application/App/File System/src/Account/FileAccounts.Page.al b/src/System Application/App/File System/src/Account/FileAccounts.Page.al
index 1c2d4a397f..a74ef92601 100644
--- a/src/System Application/App/File System/src/Account/FileAccounts.Page.al
+++ b/src/System Application/App/File System/src/Account/FileAccounts.Page.al
@@ -44,7 +44,6 @@ page 9450 "File Accounts"
ToolTip = 'Specifies the logo for the type of file account.';
Width = 1;
}
-
field(NameField; Rec.Name)
{
ToolTip = 'Specifies the name of the account.';
@@ -55,20 +54,17 @@ page 9450 "File Accounts"
ShowAccountInformation();
end;
}
-
field(NameFieldLookup; Rec.Name)
{
ToolTip = 'Specifies the name of the account.';
Visible = IsInLookupMode;
}
-
field(DefaultField; DefaultTxt)
{
Caption = 'Default';
ToolTip = 'Specifies whether the file account will be used for all scenarios for which an account is not specified. You must have a default file account, even if you have only one account.';
Visible = not IsInLookupMode;
}
-
field(FileConnector; Rec.Connector)
{
ToolTip = 'Specifies the type of file extension that the account is added to.';
@@ -77,7 +73,7 @@ page 9450 "File Accounts"
}
}
- area(factboxes)
+ area(FactBoxes)
{
part(Scenarios; "File Scenarios FactBox")
{
@@ -119,7 +115,6 @@ page 9450 "File Accounts"
end;
}
}
-
area(Processing)
{
action(MakeDefault)
@@ -175,7 +170,6 @@ page 9450 "File Accounts"
end;
}
}
-
area(Navigation)
{
action(FileScenarioSetup)
@@ -218,10 +212,7 @@ page 9450 "File Accounts"
{
}
}
- group(Category_Report)
- {
- Caption = 'Report';
- }
+
group(Category_Category4)
{
Caption = 'Navigate';
@@ -263,8 +254,8 @@ page 9450 "File Accounts"
var
FileAccount: Codeunit "File Account";
FileScenario: Codeunit "File Scenario";
- SelectedAccountId: Guid;
IsSelected: Boolean;
+ SelectedAccountId: Guid;
begin
// We need this code block to maintain the same selected record.
SelectedAccountId := Rec."Account Id";
@@ -332,6 +323,6 @@ page 9450 "File Accounts"
IsInLookupMode: Boolean;
ShowLogo: Boolean;
UpdateAccounts: Boolean;
- DefaultTxt: Text;
FileConnectorHasBeenUninstalledMsg: Label 'The selected file extension has been uninstalled. To view information about the file account, you must reinstall the extension.';
+ DefaultTxt: Text;
}
\ No newline at end of file
diff --git a/src/System Application/App/File System/src/Connector/FileSystemConnector.Interface.al b/src/System Application/App/File System/src/Connector/FileSystemConnector.Interface.al
index e104aec01c..bf6486ddae 100644
--- a/src/System Application/App/File System/src/Connector/FileSystemConnector.Interface.al
+++ b/src/System Application/App/File System/src/Connector/FileSystemConnector.Interface.al
@@ -35,7 +35,6 @@ interface "File System Connector"
/// The Stream were the file is read from.
procedure CreateFile(AccountId: Guid; Path: Text; Stream: InStream);
-
///
/// Copies as file inside the provided account.
///
@@ -44,7 +43,6 @@ interface "File System Connector"
/// The target file path.
procedure CopyFile(AccountId: Guid; SourcePath: Text; TargetPath: Text);
-
///
/// Move as file inside the provided account.
///
diff --git a/src/System Application/App/File System/src/Connector/FileSystemConnectorLogo.Table.al b/src/System Application/App/File System/src/Connector/FileSystemConnectorLogo.Table.al
index ae58ecf2d3..1437980cb1 100644
--- a/src/System Application/App/File System/src/Connector/FileSystemConnectorLogo.Table.al
+++ b/src/System Application/App/File System/src/Connector/FileSystemConnectorLogo.Table.al
@@ -31,5 +31,4 @@ table 9452 "File System Connector Logo"
Clustered = true;
}
}
-
}
\ No newline at end of file
diff --git a/src/System Application/App/File System/src/FileSystem/FileSystemImpl.Codeunit.al b/src/System Application/App/File System/src/FileSystem/FileSystemImpl.Codeunit.al
index 66902ba06b..149d3bb2f6 100644
--- a/src/System Application/App/File System/src/FileSystem/FileSystemImpl.Codeunit.al
+++ b/src/System Application/App/File System/src/FileSystem/FileSystemImpl.Codeunit.al
@@ -56,7 +56,6 @@ codeunit 9455 "File System Impl."
FileSystemConnector.CreateFile(CurrFileAccount."Account Id", Path, Stream);
end;
-
procedure CopyFile(SourcePath: Text; TargetPath: Text)
begin
CheckPath(SourcePath);
@@ -227,9 +226,9 @@ codeunit 9455 "File System Impl."
local procedure CheckPath(Path: Text)
var
- InvalidChars: Text;
InvalidChar: Char;
PathCannotStartWithSlashErr: Label 'The path %1 can not start with /.', Comment = '%1 - Path';
+ InvalidChars: Text;
begin
if Path.StartsWith('/') then
diff --git a/src/System Application/App/File System/src/Lookup/FileAccountBrowser.Page.al b/src/System Application/App/File System/src/Lookup/FileAccountBrowser.Page.al
index ea8342bff6..b247200e1d 100644
--- a/src/System Application/App/File System/src/Lookup/FileAccountBrowser.Page.al
+++ b/src/System Application/App/File System/src/Lookup/FileAccountBrowser.Page.al
@@ -21,7 +21,7 @@ page 9455 "File Account Browser"
layout
{
- area(content)
+ area(Content)
{
field(CurrentPathField; CurrentPath)
{
diff --git a/src/System Application/App/File System/src/Lookup/FileAccountBrowserMgt.Codeunit.al b/src/System Application/App/File System/src/Lookup/FileAccountBrowserMgt.Codeunit.al
index 52246f5819..038db5b9ed 100644
--- a/src/System Application/App/File System/src/Lookup/FileAccountBrowserMgt.Codeunit.al
+++ b/src/System Application/App/File System/src/Lookup/FileAccountBrowserMgt.Codeunit.al
@@ -54,9 +54,9 @@ codeunit 9458 "File Account Browser Mgt."
procedure UploadFile(Path: Text)
var
+ Stream: InStream;
UploadDialogTxt: Label 'Upload File';
FromFile: Text;
- Stream: InStream;
begin
if not UploadIntoStream(UploadDialogTxt, '', '', FromFile, Stream) then
exit;
@@ -112,8 +112,8 @@ codeunit 9458 "File Account Browser Mgt."
procedure DeleteFileOrDirectory(var TempFileAccountContent: Record "File Account Content" temporary)
var
- PathToDelete: Text;
DeleteQst: Label 'Delete %1?', Comment = '%1 - Path to Delete';
+ PathToDelete: Text;
begin
PathToDelete := FileSystem.CombinePath(TempFileAccountContent."Parent Directory", TempFileAccountContent.Name);
if not Confirm(DeleteQst, false, PathToDelete) then
diff --git a/src/System Application/App/File System/src/Lookup/FilePaginationDataImpl.Codeunit.al b/src/System Application/App/File System/src/Lookup/FilePaginationDataImpl.Codeunit.al
index 857c54dcdb..bd5738d983 100644
--- a/src/System Application/App/File System/src/Lookup/FilePaginationDataImpl.Codeunit.al
+++ b/src/System Application/App/File System/src/Lookup/FilePaginationDataImpl.Codeunit.al
@@ -12,8 +12,8 @@ codeunit 9457 "File Pagination Data Impl."
InherentEntitlements = X;
var
- Marker: Text;
EndOfListing: Boolean;
+ Marker: Text;
procedure SetMarker(NewMarker: Text)
begin
diff --git a/src/System Application/App/File System/src/Lookup/FolderNameInput.Page.al b/src/System Application/App/File System/src/Lookup/FolderNameInput.Page.al
index 42e4351ac0..8631f97b75 100644
--- a/src/System Application/App/File System/src/Lookup/FolderNameInput.Page.al
+++ b/src/System Application/App/File System/src/Lookup/FolderNameInput.Page.al
@@ -16,7 +16,7 @@ page 9456 "Folder Name Input"
layout
{
- area(content)
+ area(Content)
{
field(FolderNameField; FolderName)
{
diff --git a/src/System Application/App/File System/src/Scenario/FileAccountScenario.Table.al b/src/System Application/App/File System/src/Scenario/FileAccountScenario.Table.al
index df144f2e69..751a45e82a 100644
--- a/src/System Application/App/File System/src/Scenario/FileAccountScenario.Table.al
+++ b/src/System Application/App/File System/src/Scenario/FileAccountScenario.Table.al
@@ -21,33 +21,27 @@ table 9453 "File Account Scenario"
{
DataClassification = SystemMetadata;
}
-
field(2; Connector; Enum "File System Connector")
{
DataClassification = SystemMetadata;
}
-
field(3; "Account Id"; Guid)
{
DataClassification = SystemMetadata;
}
-
field(4; "Display Name"; Text[2048])
{
DataClassification = SystemMetadata;
}
-
field(5; Default; Boolean)
{
DataClassification = SystemMetadata;
}
-
field(6; EntryType; Option)
{
DataClassification = SystemMetadata;
OptionMembers = Account,Scenario;
}
-
field(7; Position; Integer)
{
DataClassification = SystemMetadata;
@@ -60,12 +54,9 @@ table 9453 "File Account Scenario"
{
Clustered = true;
}
-
key(Position; Position)
{
-
}
-
key(Name; "Display Name")
{
Description = 'Used for sorting by Dispay Name';
diff --git a/src/System Application/App/File System/src/Scenario/FileScenario.Table.al b/src/System Application/App/File System/src/Scenario/FileScenario.Table.al
index 723432dfea..caa1f0ae42 100644
--- a/src/System Application/App/File System/src/Scenario/FileScenario.Table.al
+++ b/src/System Application/App/File System/src/Scenario/FileScenario.Table.al
@@ -22,12 +22,10 @@ table 9454 "File Scenario"
{
DataClassification = SystemMetadata;
}
-
field(2; Connector; Enum "File System Connector")
{
DataClassification = SystemMetadata;
}
-
field(3; "Account Id"; Guid)
{
DataClassification = SystemMetadata;
diff --git a/src/System Application/App/File System/src/Scenario/FileScenarioImpl.Codeunit.al b/src/System Application/App/File System/src/Scenario/FileScenarioImpl.Codeunit.al
index a868d3c095..a83c3f4c5e 100644
--- a/src/System Application/App/File System/src/Scenario/FileScenarioImpl.Codeunit.al
+++ b/src/System Application/App/File System/src/Scenario/FileScenarioImpl.Codeunit.al
@@ -12,12 +12,12 @@ codeunit 9453 "File Scenario Impl."
Access = Internal;
InherentPermissions = X;
InherentEntitlements = X;
- Permissions = TableData "File Scenario" = rimd;
+ Permissions = tabledata "File Scenario" = rimd;
procedure GetFileAccount(Scenario: Enum "File Scenario"; var FileAccount: Record "File Account"): Boolean
var
- FileScenario: Record "File Scenario";
AllFileAccounts: Record "File Account";
+ FileScenario: Record "File Scenario";
FileAccounts: Codeunit "File Account";
begin
FileAccounts.GetAllAccounts(AllFileAccounts);
@@ -74,13 +74,13 @@ codeunit 9453 "File Scenario Impl."
/// A flatten tree structure representing the all the file accounts and the scenarios assigned to them.
procedure GetScenariosByFileAccount(var Result: Record "File Account Scenario")
var
+ DefaultAccount: Record "File Account";
FileAccounts: Record "File Account";
FileAccountScenarios: Record "File Account Scenario";
- DefaultAccount: Record "File Account";
FileAccount: Codeunit "File Account";
- DisplayName: Text[2048];
- Position: Integer;
Default: Boolean;
+ Position: Integer;
+ DisplayName: Text[2048];
begin
Result.Reset();
Result.DeleteAll();
@@ -173,9 +173,9 @@ codeunit 9453 "File Scenario Impl."
procedure AddScenarios(FileAccount: Record "File Account Scenario"): Boolean
var
- FileScenario: Record "File Scenario";
SelectedScenarios: Record "File Account Scenario";
- ScenariosForAccount: Page "File Scenarios For Account";
+ FileScenario: Record "File Scenario";
+ ScenariosForAccount: Page "File Scenarios for Account";
begin
FileAccountImpl.CheckPermissions();
diff --git a/src/System Application/App/File System/src/Scenario/FileScenarioSetup.Page.al b/src/System Application/App/File System/src/Scenario/FileScenarioSetup.Page.al
index f0c6ff309b..2f6406a154 100644
--- a/src/System Application/App/File System/src/Scenario/FileScenarioSetup.Page.al
+++ b/src/System Application/App/File System/src/Scenario/FileScenarioSetup.Page.al
@@ -43,7 +43,6 @@ page 9452 "File Scenario Setup"
Editable = false;
StyleExpr = Style;
}
-
field(Default; DefaultTxt)
{
Caption = 'Default';
@@ -63,7 +62,6 @@ page 9452 "File Scenario Setup"
action(AddScenario)
{
Visible = (TypeOfEntry = TypeOfEntry::Account) and CanUserManageFileSetup;
-
Caption = 'Assign scenarios';
ToolTip = 'Assign file scenarios for the selected file account. When assigned, everyone will use the account for the scenario. For example, if you assign the Sales Order scenario, everyone will use the account to send sales orders.';
Image = NewDocument;
@@ -85,7 +83,6 @@ page 9452 "File Scenario Setup"
action(ChangeAccount)
{
Visible = (TypeOfEntry = TypeOfEntry::Scenario) and CanUserManageFileSetup;
-
Caption = 'Reassign';
ToolTip = 'Reassign the selected scenarios to another file account.';
Image = Change;
@@ -101,11 +98,9 @@ page 9452 "File Scenario Setup"
SetSelectedRecord();
end;
}
-
action(Unassign)
{
Visible = (TypeOfEntry = TypeOfEntry::Scenario) and CanUserManageFileSetup;
-
Caption = 'Unassign';
ToolTip = 'Unassign the selected scenarios. Afterward, the default file account will be used to send files for the scenarios.';
Image = Delete;
From 93edfcfadb32639b488319caa4e7d3994ebb3ec4 Mon Sep 17 00:00:00 2001
From: Stefan Sosic
Date: Sat, 16 Nov 2024 16:30:21 +0100
Subject: [PATCH 33/43] Usings sort
---
.../App/File System/src/Account/FileAccountImpl.Codeunit.al | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/System Application/App/File System/src/Account/FileAccountImpl.Codeunit.al b/src/System Application/App/File System/src/Account/FileAccountImpl.Codeunit.al
index d9580a3d53..07a4ce0648 100644
--- a/src/System Application/App/File System/src/Account/FileAccountImpl.Codeunit.al
+++ b/src/System Application/App/File System/src/Account/FileAccountImpl.Codeunit.al
@@ -5,8 +5,8 @@
namespace System.FileSystem;
-using System.Utilities;
using System.Text;
+using System.Utilities;
codeunit 9451 "File Account Impl."
{
From 33b84fb06801ca1b94a0262d7a1ef0cd4c01b6b9 Mon Sep 17 00:00:00 2001
From: Stefan Sosic
Date: Sat, 16 Nov 2024 16:39:41 +0100
Subject: [PATCH 34/43] Brief in app.json
---
src/System Application/App/File System/app.json | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/System Application/App/File System/app.json b/src/System Application/App/File System/app.json
index 0a45dc0288..63dffae392 100644
--- a/src/System Application/App/File System/app.json
+++ b/src/System Application/App/File System/app.json
@@ -2,7 +2,7 @@
"id": "c9c54414-80c3-4cc9-98c6-589158882774",
"name": "File System",
"publisher": "Microsoft",
- "brief": "Enables access to external file systems from Business Central.",
+ "brief": "Access external file systems",
"description": "Enables access to external file systems from Business Central.",
"version": "26.0.0.0",
"privacyStatement": "https://go.microsoft.com/fwlink/?linkid=724009",
From 49c0b7b710382979f9fa7d5057809db53f306956 Mon Sep 17 00:00:00 2001
From: Stefan Sosic
Date: Sat, 16 Nov 2024 16:39:50 +0100
Subject: [PATCH 35/43] README
---
src/System Application/App/File System/README.md | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/src/System Application/App/File System/README.md b/src/System Application/App/File System/README.md
index aa74a80495..b8a84d99c0 100644
--- a/src/System Application/App/File System/README.md
+++ b/src/System Application/App/File System/README.md
@@ -1,6 +1,7 @@
-Provides an API that lets you connect file system accounts to Business Central so that people can access files outside BC. The file system module consists of the following main entities:
+# File System Module for Business Central
+Provides an API that lets you connect file system accounts to Business Central so that people can access files outside BC.
-### File Account
-An file account holds the information needed to access a file system from Business Central.
+## Main Components
-...
\ No newline at end of file
+### File Account
+A file account holds the information needed to access a file system from Business Central.
From 63e15eb2b06781927a3e989ed2a64b10399cf405 Mon Sep 17 00:00:00 2001
From: Stefan Sosic
Date: Sat, 16 Nov 2024 16:40:05 +0100
Subject: [PATCH 36/43] Description
---
.../App/File System/permissions/FileSystemRead.PermissionSet.al | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/System Application/App/File System/permissions/FileSystemRead.PermissionSet.al b/src/System Application/App/File System/permissions/FileSystemRead.PermissionSet.al
index d0f2bffde8..77e7129b9f 100644
--- a/src/System Application/App/File System/permissions/FileSystemRead.PermissionSet.al
+++ b/src/System Application/App/File System/permissions/FileSystemRead.PermissionSet.al
@@ -18,5 +18,5 @@ permissionset 9451 "File System - Read"
tabledata "File Account Scenario" = r,
tabledata "File Scenario" = r,
tabledata "File Account Content" = r,
- tabledata Media = r; // File System Account Wizard requires this
+ tabledata Media = r; // This permission is required by File System Account Wizard
}
\ No newline at end of file
From 797739771d40ed5836388c3beca5644cb8c84f6f Mon Sep 17 00:00:00 2001
From: Stefan Sosic
Date: Sat, 16 Nov 2024 17:15:38 +0100
Subject: [PATCH 37/43] Fixing english
---
.../src/Account/FileAccount.Table.al | 2 +-
.../src/Account/FileAccountImpl.Codeunit.al | 4 ++--
.../src/Account/FileAccountWizard.Page.al | 4 ++--
.../src/Account/FileAccounts.Page.al | 6 ++---
.../FileSystemConnector.Interface.al | 10 ++++----
.../src/FileSystem/FileSystem.Codeunit.al | 24 +++++++++----------
.../src/FileSystem/FileSystemImpl.Codeunit.al | 10 ++++----
.../Lookup/FileAccountBrowserMgt.Codeunit.al | 8 +++----
.../src/Lookup/FilePaginationData.Codeunit.al | 6 ++---
.../File System/src/Lookup/FileType.Enum.al | 4 ++--
.../src/Scenario/FileAccountScenario.Table.al | 4 ++--
.../src/Scenario/FileScenario.Codeunit.al | 6 ++---
.../src/Scenario/FileScenarioImpl.Codeunit.al | 4 ++--
.../src/Scenario/FileScenarioSetup.Page.al | 2 +-
.../Scenario/FileScenariosForAccount.Page.al | 2 +-
15 files changed, 48 insertions(+), 48 deletions(-)
diff --git a/src/System Application/App/File System/src/Account/FileAccount.Table.al b/src/System Application/App/File System/src/Account/FileAccount.Table.al
index 97803e2be2..c149061766 100644
--- a/src/System Application/App/File System/src/Account/FileAccount.Table.al
+++ b/src/System Application/App/File System/src/Account/FileAccount.Table.al
@@ -6,7 +6,7 @@
namespace System.FileSystem;
///
-/// A common representation of an file account.
+/// A common representation of a file account.
///
table 9450 "File Account"
{
diff --git a/src/System Application/App/File System/src/Account/FileAccountImpl.Codeunit.al b/src/System Application/App/File System/src/Account/FileAccountImpl.Codeunit.al
index 07a4ce0648..2d285ed4a4 100644
--- a/src/System Application/App/File System/src/Account/FileAccountImpl.Codeunit.al
+++ b/src/System Application/App/File System/src/Account/FileAccountImpl.Codeunit.al
@@ -65,7 +65,7 @@ codeunit 9451 "File Account Impl."
// Get the current default account to track if it was deleted
FileScenario.GetDefaultFileAccount(CurrentDefaultFileAccount);
- // Delete all selected acounts
+ // Delete all selected accounts
repeat
// Check to validate that the connector is still installed
// The connector could have been uninstalled by another user/session
@@ -98,7 +98,7 @@ codeunit 9451 "File Account Impl."
exit;
end;
- Commit(); // Commit the accounts deletion in order to prompt for new default account
+ Commit(); // Commit the accounts deletion in order to prompt for a new default account
if PromptNewDefaultAccountChoice(NewDefaultFileAccount) then
MakeDefault(NewDefaultFileAccount)
else
diff --git a/src/System Application/App/File System/src/Account/FileAccountWizard.Page.al b/src/System Application/App/File System/src/Account/FileAccountWizard.Page.al
index 4ca67643cf..100812085f 100644
--- a/src/System Application/App/File System/src/Account/FileAccountWizard.Page.al
+++ b/src/System Application/App/File System/src/Account/FileAccountWizard.Page.al
@@ -87,7 +87,7 @@ page 9451 "File Account Wizard"
group(Privacy)
{
Caption = 'Privacy notice';
- InstructionalText = 'By adding an file account you acknowledge that the file provider might be able to access the data you send in files from Business Central.';
+ InstructionalText = 'By adding a file account you acknowledge that the file provider might be able to access the data you send in files from Business Central.';
}
group(GetStartedText)
{
@@ -213,7 +213,7 @@ page 9451 "File Account Wizard"
group(Account)
{
Caption = 'Account';
- field(Namefield; RegisteredAccount.Name)
+ field(NameField; RegisteredAccount.Name)
{
Editable = false;
Caption = 'Name';
diff --git a/src/System Application/App/File System/src/Account/FileAccounts.Page.al b/src/System Application/App/File System/src/Account/FileAccounts.Page.al
index a74ef92601..8a07f2596a 100644
--- a/src/System Application/App/File System/src/Account/FileAccounts.Page.al
+++ b/src/System Application/App/File System/src/Account/FileAccounts.Page.al
@@ -103,8 +103,8 @@ page 9450 "File Accounts"
action(AddAccount)
{
Image = Add;
- Caption = 'Add an file account';
- ToolTip = 'Opens a File Account Wizard setup page in order to add an File Account.';
+ Caption = 'Add a file account';
+ ToolTip = 'Opens a File Account Wizard setup page in order to add a file account.';
Visible = (not IsInLookupMode) and CanUserManageFileSetup;
trigger OnAction()
@@ -298,7 +298,7 @@ page 9450 "File Accounts"
end;
///
- /// Sets an file account to be selected.
+ /// Sets a file account to be selected.
///
/// The file account to be initially selected on the page
procedure SetAccount(var FileAccount: Record "File Account")
diff --git a/src/System Application/App/File System/src/Connector/FileSystemConnector.Interface.al b/src/System Application/App/File System/src/Connector/FileSystemConnector.Interface.al
index bf6486ddae..7dbfd39386 100644
--- a/src/System Application/App/File System/src/Connector/FileSystemConnector.Interface.al
+++ b/src/System Application/App/File System/src/Connector/FileSystemConnector.Interface.al
@@ -6,7 +6,7 @@
namespace System.FileSystem;
///
-/// An File System Connector interface used to creating file accounts and handle external files.
+/// A File System Connector interface used to create file accounts and handle external files.
///
interface "File System Connector"
{
@@ -104,13 +104,13 @@ interface "File System Connector"
procedure GetAccounts(var Accounts: Record "File Account");
///
- /// Shows the information for an file account.
+ /// Shows the information for a file account.
///
/// The ID of the file account
procedure ShowAccountInformation(AccountId: Guid);
///
- /// Registers an file account for the connector.
+ /// Registers a file account for the connector.
///
/// The out parameter must hold the account ID of the added account.
/// Out parameter with the details of the registered Account.
@@ -118,7 +118,7 @@ interface "File System Connector"
procedure RegisterAccount(var FileAccount: Record "File Account"): Boolean
///
- /// Deletes an file account for the connector.
+ /// Deletes a file account for the connector.
///
/// The ID of the file account
/// True if an account was deleted.
@@ -128,7 +128,7 @@ interface "File System Connector"
/// Provides a custom logo for the connector that shows in the Setup File Account Guide.
///
/// Base64 encoded image.
- /// The recomended image size is 128x128.
+ /// The recommended image size is 128x128.
/// The logo of the connector is Base64 format
procedure GetLogoAsBase64(): Text;
diff --git a/src/System Application/App/File System/src/FileSystem/FileSystem.Codeunit.al b/src/System Application/App/File System/src/FileSystem/FileSystem.Codeunit.al
index c6b9fc49fa..6a46897536 100644
--- a/src/System Application/App/File System/src/FileSystem/FileSystem.Codeunit.al
+++ b/src/System Application/App/File System/src/FileSystem/FileSystem.Codeunit.al
@@ -14,7 +14,7 @@ codeunit 9454 "File System"
FileSystemImpl: Codeunit "File System Impl.";
///
- /// Initialized the File System for the give scenario.
+ /// Initialized the File System for the given scenario.
///
/// File Scenario to use.
procedure Initialize(Scenario: Enum "File Scenario")
@@ -131,7 +131,7 @@ codeunit 9454 "File System"
///
/// Checks if a specific directory exists in the file account.
///
- /// Path of the directry to check.
+ /// Path of the directory to check.
/// Returns true if directory exists.
procedure DirectoryExists(Path: Text): Boolean
begin
@@ -162,8 +162,8 @@ codeunit 9454 "File System"
///
/// Gets the Parent Path of the given path.
///
- /// File or directoy path.
- /// The parent of the speicfied path.
+ /// File or directory path.
+ /// The parent of the specified path.
procedure GetParentPath(Path: Text): Text
begin
exit(FileSystemImpl.GetParentPath(Path));
@@ -176,9 +176,9 @@ codeunit 9454 "File System"
/// Returns the selected Folder.
procedure SelectFolderUI(Path: Text): Text
var
- DefaulSelectFolderUILbl: Label 'Select a folder';
+ DefaultSelectFolderUILbl: Label 'Select a folder';
begin
- exit(SelectFolderUI(Path, DefaulSelectFolderUILbl));
+ exit(SelectFolderUI(Path, DefaultSelectFolderUILbl));
end;
///
@@ -200,9 +200,9 @@ codeunit 9454 "File System"
/// Returns the path of the selected file.
procedure SelectFileUI(Path: Text; FileFilter: Text): Text
var
- DefaulSelectFileUILbl: Label 'Select a file';
+ DefaultSelectFileUILbl: Label 'Select a file';
begin
- exit(SelectFileUI(Path, FileFilter, DefaulSelectFileUILbl));
+ exit(SelectFileUI(Path, FileFilter, DefaultSelectFileUILbl));
end;
///
@@ -221,8 +221,8 @@ codeunit 9454 "File System"
/// Opens a save to dialog.
///
/// Start path of the dialog.
- /// The fileextion without dot (like pdf or txt).
- /// Returns the selecte file path.
+ /// The file extension without dot (like pdf or txt).
+ /// Returns the selected file path.
procedure SaveFileUI(Path: Text; FileExtension: Text): Text
var
DefaultSaveFileUITitleLbl: Label 'Save as';
@@ -234,9 +234,9 @@ codeunit 9454 "File System"
/// Opens a save to dialog.
///
/// Start path of the dialog.
- /// The fileextion without dot (like pdf or txt).
+ /// The file extension without dot (like pdf or txt).
/// Title of the selection dialog.
- /// Returns the selecte file path.
+ /// Returns the selected file path.
procedure SaveFileUI(Path: Text; FileExtension: Text; DialogTitle: Text): Text
begin
exit(FileSystemImpl.SaveFileUI(Path, FileExtension, DialogTitle));
diff --git a/src/System Application/App/File System/src/FileSystem/FileSystemImpl.Codeunit.al b/src/System Application/App/File System/src/FileSystem/FileSystemImpl.Codeunit.al
index 149d3bb2f6..16debc259e 100644
--- a/src/System Application/App/File System/src/FileSystem/FileSystemImpl.Codeunit.al
+++ b/src/System Application/App/File System/src/FileSystem/FileSystemImpl.Codeunit.al
@@ -20,7 +20,7 @@ codeunit 9455 "File System Impl."
var
FileAccount: Record "File Account";
FileScenario: Codeunit "File Scenario";
- NoFileAccountFoundErr: Label 'No defaut file account defined.';
+ NoFileAccountFoundErr: Label 'No default file account defined.';
begin
if not FileScenario.GetFileAccount(Scenario, FileAccount) then
Error(NoFileAccountFoundErr);
@@ -182,7 +182,7 @@ codeunit 9455 "File System Impl."
procedure SaveFileUI(Path: Text; FileExtension: Text; DialogTitle: Text): Text
var
FileAccountBrowser: Page "File Account Browser";
- FileName, FileNameWithExtenion : Text;
+ FileName, FileNameWithExtension : Text;
PleaseProvideFileExtensionErr: Label 'Please provide a valid file extension.';
FileNameTok: Label '%1.%2', Locked = true;
begin
@@ -202,8 +202,8 @@ codeunit 9455 "File System Impl."
if FileName = '' then
exit('');
- FileNameWithExtenion := StrSubstNo(FileNameTok, FileName, FileExtension);
- exit(CombinePath(FileAccountBrowser.GetCurrentDirectory(), FileNameWithExtenion));
+ FileNameWithExtension := StrSubstNo(FileNameTok, FileName, FileExtension);
+ exit(CombinePath(FileAccountBrowser.GetCurrentDirectory(), FileNameWithExtension));
end;
procedure BrowseAccount()
@@ -216,7 +216,7 @@ codeunit 9455 "File System Impl."
local procedure CheckInitialization()
var
- NotInitializedErr: Label 'Please call Initalize() first.';
+ NotInitializedErr: Label 'Please call Initialize() first.';
begin
if IsInitialized then
exit;
diff --git a/src/System Application/App/File System/src/Lookup/FileAccountBrowserMgt.Codeunit.al b/src/System Application/App/File System/src/Lookup/FileAccountBrowserMgt.Codeunit.al
index 038db5b9ed..abcfe1247d 100644
--- a/src/System Application/App/File System/src/Lookup/FileAccountBrowserMgt.Codeunit.al
+++ b/src/System Application/App/File System/src/Lookup/FileAccountBrowserMgt.Codeunit.al
@@ -19,11 +19,11 @@ codeunit 9458 "File Account Browser Mgt."
FileSystem.Initialize(FileAccount);
end;
- procedure StripNotsupportChrInFileName(InText: Text): Text
+ procedure StripNotSupportedCharsInFileName(InText: Text): Text
var
- InvalidChrStringTxt: Label '"#%&*:<>?\/{|}~', Locked = true;
+ InvalidCharsStringTxt: Label '"#%&*:<>?\/{|}~', Locked = true;
begin
- InText := DelChr(InText, '=', InvalidChrStringTxt);
+ InText := DelChr(InText, '=', InvalidCharsStringTxt);
exit(InText);
end;
@@ -72,7 +72,7 @@ codeunit 9458 "File Account Browser Mgt."
if FolderNameInput.RunModal() <> Action::OK then
exit;
- FolderName := StripNotsupportChrInFileName(FolderNameInput.GetFolderName());
+ FolderName := StripNotSupportedCharsInFileName(FolderNameInput.GetFolderName());
FileSystem.CreateDirectory(FileSystem.CombinePath(Path, FolderName));
end;
diff --git a/src/System Application/App/File System/src/Lookup/FilePaginationData.Codeunit.al b/src/System Application/App/File System/src/Lookup/FilePaginationData.Codeunit.al
index 25637a4c53..87cdfb4a06 100644
--- a/src/System Application/App/File System/src/Lookup/FilePaginationData.Codeunit.al
+++ b/src/System Application/App/File System/src/Lookup/FilePaginationData.Codeunit.al
@@ -14,7 +14,7 @@ codeunit 9456 "File Pagination Data"
FilePaginationDataImpl: Codeunit "File Pagination Data Impl.";
///
- /// Sets a marker if files and directories can be getted in batches.
+ /// Sets a marker to see if files and directories can be retrieved in batches.
///
/// Marker value to set.
procedure SetMarker(NewMarker: Text)
@@ -32,7 +32,7 @@ codeunit 9456 "File Pagination Data"
end;
///
- /// Set this value to true, if all files or directoreis have beend read a from the File System.
+ /// Set this value to true, if all files or directories have been read a from the File System.
///
/// End of listing reached.
procedure SetEndOfListing(NewEndOfListing: Boolean)
@@ -41,7 +41,7 @@ codeunit 9456 "File Pagination Data"
end;
///
- /// Defines if all batches of directory or file listing has beend received.
+ /// Defines if all batches of directory or file listing has been received.
///
/// End of listing reached.
procedure IsEndOfListing(): Boolean
diff --git a/src/System Application/App/File System/src/Lookup/FileType.Enum.al b/src/System Application/App/File System/src/Lookup/FileType.Enum.al
index 7e814d99bf..4fa30d0589 100644
--- a/src/System Application/App/File System/src/Lookup/FileType.Enum.al
+++ b/src/System Application/App/File System/src/Lookup/FileType.Enum.al
@@ -14,7 +14,7 @@ enum 9452 "File Type"
Extensible = false;
///
- /// Indicates if entry is a directory.
+ /// Indicates if entry is a directory.
///
value(0; Directory)
{
@@ -22,7 +22,7 @@ enum 9452 "File Type"
}
///
- /// Indicates if entry is a file type.
+ /// Indicates if entry is a file type.
///
value(1; File)
{
diff --git a/src/System Application/App/File System/src/Scenario/FileAccountScenario.Table.al b/src/System Application/App/File System/src/Scenario/FileAccountScenario.Table.al
index 751a45e82a..209cd7ef9b 100644
--- a/src/System Application/App/File System/src/Scenario/FileAccountScenario.Table.al
+++ b/src/System Application/App/File System/src/Scenario/FileAccountScenario.Table.al
@@ -6,7 +6,7 @@
namespace System.FileSystem;
///
-/// Temporary table used to display the tree sctructure in "File Scenario Setup".
+/// Temporary table used to display the tree structure in "File Scenario Setup".
///
table 9453 "File Account Scenario"
{
@@ -59,7 +59,7 @@ table 9453 "File Account Scenario"
}
key(Name; "Display Name")
{
- Description = 'Used for sorting by Dispay Name';
+ Description = 'Used for sorting by Display Name';
}
}
}
\ No newline at end of file
diff --git a/src/System Application/App/File System/src/Scenario/FileScenario.Codeunit.al b/src/System Application/App/File System/src/Scenario/FileScenario.Codeunit.al
index d76f7df612..6bc25d5574 100644
--- a/src/System Application/App/File System/src/Scenario/FileScenario.Codeunit.al
+++ b/src/System Application/App/File System/src/Scenario/FileScenario.Codeunit.al
@@ -17,7 +17,7 @@ codeunit 9452 "File Scenario"
/// Gets the default file account.
///
/// Out parameter holding information about the default file account.
- /// True if an account for the the default scenario was found; otherwise - false.
+ /// True if an account for the default scenario was found; otherwise - false.
procedure GetDefaultFileAccount(var FileAccount: Record "File Account"): Boolean
begin
exit(FileScenarioImpl.GetFileAccount(Enum::"File Scenario"::Default, FileAccount));
@@ -45,9 +45,9 @@ codeunit 9452 "File Scenario"
end;
///
- /// Sets an file account to be used by the given file scenario.
+ /// Sets a file account to be used by the given file scenario.
///
- /// The scenario for which to set an file account.
+ /// The scenario for which to set a file account.
/// The file account to use.
procedure SetFileAccount(Scenario: Enum "File Scenario"; FileAccount: Record "File Account")
begin
diff --git a/src/System Application/App/File System/src/Scenario/FileScenarioImpl.Codeunit.al b/src/System Application/App/File System/src/Scenario/FileScenarioImpl.Codeunit.al
index a83c3f4c5e..291638f58c 100644
--- a/src/System Application/App/File System/src/Scenario/FileScenarioImpl.Codeunit.al
+++ b/src/System Application/App/File System/src/Scenario/FileScenarioImpl.Codeunit.al
@@ -63,7 +63,7 @@ codeunit 9453 "File Scenario Impl."
end;
///
- /// Get a list of entries, representing a tree structure with file accounts and the scenarios, assigned to each accout.
+ /// Get a list of entries, representing a tree structure with file accounts and the scenarios, assigned to each account.
///
///
/// Account sales@cronus.com has scenarios "Sales Quote" and "Sales Credit Memo" assigned.
@@ -71,7 +71,7 @@ codeunit 9453 "File Scenario Impl."
/// The result of calling the function will be:
/// sales@cronus.com, "Sales Quote", "Sales Credit Memo", purchase@cronus.com, "Purchase Quote", "Purchase Invoice"
///
- /// A flatten tree structure representing the all the file accounts and the scenarios assigned to them.
+ /// A flattened tree structure representing all the file accounts and the scenarios assigned to them.
procedure GetScenariosByFileAccount(var Result: Record "File Account Scenario")
var
DefaultAccount: Record "File Account";
diff --git a/src/System Application/App/File System/src/Scenario/FileScenarioSetup.Page.al b/src/System Application/App/File System/src/Scenario/FileScenarioSetup.Page.al
index 2f6406a154..da761208d2 100644
--- a/src/System Application/App/File System/src/Scenario/FileScenarioSetup.Page.al
+++ b/src/System Application/App/File System/src/Scenario/FileScenarioSetup.Page.al
@@ -167,7 +167,7 @@ page 9452 "File Scenario Setup"
end;
end;
- // Used to set the focus on an file account
+ // Used to set the focus on a file account
internal procedure SetFileAccountId(AccountId: Guid; Connector: Enum "File System Connector")
begin
FileAccountId := AccountId;
diff --git a/src/System Application/App/File System/src/Scenario/FileScenariosForAccount.Page.al b/src/System Application/App/File System/src/Scenario/FileScenariosForAccount.Page.al
index 53dfcaf231..d9bc412c3a 100644
--- a/src/System Application/App/File System/src/Scenario/FileScenariosForAccount.Page.al
+++ b/src/System Application/App/File System/src/Scenario/FileScenariosForAccount.Page.al
@@ -60,7 +60,7 @@ page 9454 "File Scenarios for Account"
begin
FileScenarioImpl.GetAvailableScenariosForAccount(Rec, Rec);
Rec.SetCurrentKey("Display Name");
- if Rec.FindFirst() then; // set the selection to the first record
+ if Rec.FindFirst() then; // Set the selection to the first record
end;
var
From d368497ee09d9dd36276edcd73eb20ad8019e520 Mon Sep 17 00:00:00 2001
From: Stefan Sosic
Date: Sat, 16 Nov 2024 17:21:34 +0100
Subject: [PATCH 38/43] Fix tests
---
.../src/FileScenarioPageTest.Codeunit.al | 6 ++--
.../src/FileScenarioTest.Codeunit.al | 34 +++++++++----------
2 files changed, 20 insertions(+), 20 deletions(-)
diff --git a/src/System Application/Test/File System/src/FileScenarioPageTest.Codeunit.al b/src/System Application/Test/File System/src/FileScenarioPageTest.Codeunit.al
index 8d16e5767b..43c2fe0219 100644
--- a/src/System Application/Test/File System/src/FileScenarioPageTest.Codeunit.al
+++ b/src/System Application/Test/File System/src/FileScenarioPageTest.Codeunit.al
@@ -122,7 +122,7 @@ codeunit 134751 "File Scenario Page Test"
FileAccount: Record "File Account";
FileScenarioPage: TestPage "File Scenario Setup";
begin
- // [Scenario] Having one default account with a non-default scenario assigned displays propely on "File Scenario Setup"
+ // [Scenario] Having one default account with a non-default scenario assigned displays properly on "File Scenario Setup"
PermissionsMock.Set('File System Admin');
// [Given] One file account is registered and it's set as default.
@@ -152,7 +152,7 @@ codeunit 134751 "File Scenario Page Test"
FileScenarioPage.Expand(true);
Assert.IsTrue(FileScenarioPage.Next(), 'There should be another entry on the page');
- // Properies are as expected
+ // Properties are as expected
Assert.AreEqual(Format(Enum::"File Scenario"::"Test File Scenario"), FileScenarioPage.Name.Value, 'Wrong entry name');
Assert.IsFalse(GetDefaultFieldValueAsBoolean(FileScenarioPage.Default.Value), 'The account should not be marked as default');
@@ -186,7 +186,7 @@ codeunit 134751 "File Scenario Page Test"
FileScenarioPage.Trap();
FileScenarioPage.OpenView();
- // [Then] There are three entries on the page. One is set as dedault
+ // [Then] There are three entries on the page. One is set as default
Assert.IsTrue(FileScenarioPage.GoToKey(-1, FirstFileAccount."Account Id", FirstFileAccount.Connector), 'There should be data on the page');
Assert.AreEqual(StrSubstNo(DisplayNameTxt, FirstFileAccount.Name), FileScenarioPage.Name.Value, 'Wrong first entry name');
Assert.IsTrue(GetDefaultFieldValueAsBoolean(FileScenarioPage.Default.Value), 'The account should be marked as default');
diff --git a/src/System Application/Test/File System/src/FileScenarioTest.Codeunit.al b/src/System Application/Test/File System/src/FileScenarioTest.Codeunit.al
index 6d6a4f7862..fcc5e035ce 100644
--- a/src/System Application/Test/File System/src/FileScenarioTest.Codeunit.al
+++ b/src/System Application/Test/File System/src/FileScenarioTest.Codeunit.al
@@ -35,7 +35,7 @@ codeunit 134752 "File Scenario Test"
Initialize();
// [When] calling GetFileAccount
- // [Then] false is retuned
+ // [Then] false is returned
Assert.IsFalse(FileScenario.GetFileAccount(Enum::"File Scenario"::"Test File Scenario", FileAccount), 'There should not be any account');
end;
@@ -55,7 +55,7 @@ codeunit 134752 "File Scenario Test"
FileScenarioMock.AddMapping(Enum::"File Scenario"::"Test File Scenario", NonExistentAccountId, Enum::"File System Connector"::"Test File System Connector");
// [When] calling GetFileAccount
- // [Then] false is retuned
+ // [Then] false is returned
Assert.IsFalse(FileScenario.GetFileAccount(Enum::"File Scenario"::"Test File Scenario", FileAccount), 'There should not be any account mapped to the scenario');
end;
@@ -75,7 +75,7 @@ codeunit 134752 "File Scenario Test"
FileScenarioMock.AddMapping(Enum::"File Scenario"::Default, NonExistentAccountId, Enum::"File System Connector"::"Test File System Connector");
// [When] calling GetFileAccount
- // [Then] false is retuned
+ // [Then] false is returned
Assert.IsFalse(FileScenario.GetFileAccount(Enum::"File Scenario"::"Test File Scenario", FileAccount), 'There should not be any account mapped to the scenario');
end;
@@ -95,7 +95,7 @@ codeunit 134752 "File Scenario Test"
FileScenarioMock.AddMapping(Enum::"File Scenario"::Default, AccountId, Enum::"File System Connector"::"Test File System Connector");
// [When] calling GetFileAccount
- // [Then] true is retuned and the File account is as expected
+ // [Then] true is returned and the File account is as expected
Assert.IsTrue(FileScenario.GetFileAccount(Enum::"File Scenario"::"Test File Scenario", FileAccount), 'There should be an File account');
Assert.AreEqual(AccountId, FileAccount."Account Id", 'Wrong account ID');
Assert.AreEqual(Enum::"File System Connector"::"Test File System Connector", FileAccount.Connector, 'Wrong connector');
@@ -117,7 +117,7 @@ codeunit 134752 "File Scenario Test"
FileScenarioMock.AddMapping(Enum::"File Scenario"::"Test File Scenario", AccountId, Enum::"File System Connector"::"Test File System Connector");
// [When] calling GetFileAccount
- // [Then] true is retuned and the File account is as expected
+ // [Then] true is returned and the File account is as expected
Assert.IsTrue(FileScenario.GetFileAccount(Enum::"File Scenario"::"Test File Scenario", FileAccount), 'There should be an File account');
Assert.AreEqual(AccountId, FileAccount."Account Id", 'Wrong account ID');
Assert.AreEqual(Enum::"File System Connector"::"Test File System Connector", FileAccount.Connector, 'Wrong connector');
@@ -131,10 +131,10 @@ codeunit 134752 "File Scenario Test"
AccountId: Guid;
DefaultAccountId: Guid;
begin
- // [Scenario] When the File scenario and the default scenarion are mapped to different File accounts, GetFileAccount returns the corrent account
+ // [Scenario] When the File scenario and the default scenario are mapped to different File accounts, GetFileAccount returns the correct account
PermissionsMock.Set('File System Admin');
- // [Given] An File scenario is mapped to an account, the default scenarion is mapped to another account
+ // [Given] An File scenario is mapped to an account, the default scenario is mapped to another account
Initialize();
FileConnectorMock.AddAccount(AccountId);
FileConnectorMock.AddAccount(DefaultAccountId);
@@ -142,7 +142,7 @@ codeunit 134752 "File Scenario Test"
FileScenarioMock.AddMapping(Enum::"File Scenario"::Default, DefaultAccountId, Enum::"File System Connector"::"Test File System Connector");
// [When] calling GetFileAccount
- // [Then] true is retuned and the File accounts are as expected
+ // [Then] true is returned and the File accounts are as expected
Assert.IsTrue(FileScenario.GetFileAccount(Enum::"File Scenario"::"Test File Scenario", FileAccount), 'There should be an File account');
Assert.AreEqual(AccountId, FileAccount."Account Id", 'Wrong account ID');
Assert.AreEqual(Enum::"File System Connector"::"Test File System Connector", FileAccount.Connector, 'Wrong connector');
@@ -160,10 +160,10 @@ codeunit 134752 "File Scenario Test"
NonExistingAccountId: Guid;
DefaultAccountId: Guid;
begin
- // [Scenario] When the File scenario is mapped to a non-existing account and the default scenarion is mapped to an existing accounts, GetFileAccount returns the corrent account
+ // [Scenario] When the File scenario is mapped to a non-existing account and the default scenario is mapped to an existing accounts, GetFileAccount returns the correct account
PermissionsMock.Set('File System Admin');
- // [Given] An File scenario is mapped to a non-exisitng account, the default scenarion is mapped to an existing account
+ // [Given] An File scenario is mapped to a non-existing account, the default scenario is mapped to an existing account
Initialize();
FileConnectorMock.AddAccount(DefaultAccountId);
NonExistingAccountId := Any.GuidValue();
@@ -171,7 +171,7 @@ codeunit 134752 "File Scenario Test"
FileScenarioMock.AddMapping(Enum::"File Scenario"::Default, DefaultAccountId, Enum::"File System Connector"::"Test File System Connector");
// [When] calling GetFileAccount
- // [Then] true is retuned and the File accounts are as expected
+ // [Then] true is returned and the File accounts are as expected
Assert.IsTrue(FileScenario.GetFileAccount(Enum::"File Scenario"::"Test File Scenario", FileAccount), 'There should be an File account');
Assert.AreEqual(DefaultAccountId, FileAccount."Account Id", 'Wrong account ID');
Assert.AreEqual(Enum::"File System Connector"::"Test File System Connector", FileAccount.Connector, 'Wrong connector');
@@ -189,10 +189,10 @@ codeunit 134752 "File Scenario Test"
AccountId: Guid;
DefaultAccountId: Guid;
begin
- // [Scenario] When the File scenario is mapped to an existing account and the default scenarion is mapped to a non-existing accounts, GetFileAccount returns the corrent account
+ // [Scenario] When the File scenario is mapped to an existing account and the default scenario is mapped to a non-existing accounts, GetFileAccount returns the correct account
PermissionsMock.Set('File System Admin');
- // [Given] An File scenario is mapped to an exisitng account, the default scenarion is mapped to a non-existing account
+ // [Given] An File scenario is mapped to an existing account, the default scenario is mapped to a non-existing account
Initialize();
FileConnectorMock.AddAccount(AccountId);
DefaultAccountId := Any.GuidValue();
@@ -200,7 +200,7 @@ codeunit 134752 "File Scenario Test"
FileScenarioMock.AddMapping(Enum::"File Scenario"::Default, DefaultAccountId, Enum::"File System Connector"::"Test File System Connector");
// [When] calling GetFileAccount
- // [Then] true is retuned and the File account is as expected
+ // [Then] true is returned and the File account is as expected
Assert.IsTrue(FileScenario.GetFileAccount(Enum::"File Scenario"::"Test File Scenario", FileAccount), 'There should be an File account');
Assert.AreEqual(AccountId, FileAccount."Account Id", 'Wrong account ID');
Assert.AreEqual(Enum::"File System Connector"::"Test File System Connector", FileAccount.Connector, 'Wrong connector');
@@ -234,18 +234,18 @@ codeunit 134752 "File Scenario Test"
// [Then] The scenario exists and is as expected
Assert.IsTrue(FileSystemTestLib.GetFileScenarioAccountIdAndFileConnector(Scenario, AccountId, FileSystemConnector), 'The File scenario should exist');
- Assert.AreEqual(AccountId, FileAccount."Account Id", 'Wrong accound ID');
+ Assert.AreEqual(AccountId, FileAccount."Account Id", 'Wrong account ID');
Assert.AreEqual(Enum::"File System Connector"::"Test File System Connector", FileAccount.Connector, 'Wrong connector');
AnotherAccount."Account Id" := Any.GuidValue();
AnotherAccount.Connector := Enum::"File System Connector"::"Test File System Connector";
- // [When] Setting overwting the File account for the scenario
+ // [When] Setting overwriting the File account for the scenario
FileScenario.SetFileAccount(Scenario, AnotherAccount);
// [Then] The scenario still exists and is as expected
Assert.IsTrue(FileSystemTestLib.GetFileScenarioAccountIdAndFileConnector(Scenario, AccountId, FileSystemConnector), 'The File scenario should exist');
- Assert.AreEqual(AccountId, AnotherAccount."Account Id", 'Wrong accound ID');
+ Assert.AreEqual(AccountId, AnotherAccount."Account Id", 'Wrong account ID');
Assert.AreEqual(Enum::"File System Connector"::"Test File System Connector", AnotherAccount.Connector, 'Wrong connector');
end;
From 55265be234e4af85dee53a90b37816bf50a7dd27 Mon Sep 17 00:00:00 2001
From: Stefan Sosic
Date: Sat, 16 Nov 2024 17:22:35 +0100
Subject: [PATCH 39/43] Fix
---
.../src/Mock/FileConnectorMock.Codeunit.al | 2 +-
.../File System/src/Mock/FileScenarioMock.Codeunit.al | 1 -
.../src/Mock/FileSystemAccSelectionMock.Codeunit.al | 2 +-
.../File System/src/TestFileAccount.Table.al | 1 -
.../src/TestFileSystemConnector.Codeunit.al | 11 -----------
5 files changed, 2 insertions(+), 15 deletions(-)
diff --git a/src/System Application/Test Library/File System/src/Mock/FileConnectorMock.Codeunit.al b/src/System Application/Test Library/File System/src/Mock/FileConnectorMock.Codeunit.al
index 2a41d93300..f3094e4ab9 100644
--- a/src/System Application/Test Library/File System/src/Mock/FileConnectorMock.Codeunit.al
+++ b/src/System Application/Test Library/File System/src/Mock/FileConnectorMock.Codeunit.al
@@ -15,8 +15,8 @@ codeunit 135810 "File Connector Mock"
procedure Initialize()
var
- TestFileConnectorSetup: Record "Test File Connector Setup";
TestFileAccount: Record "Test File Account";
+ TestFileConnectorSetup: Record "Test File Connector Setup";
begin
TestFileConnectorSetup.DeleteAll();
TestFileConnectorSetup.Init();
diff --git a/src/System Application/Test Library/File System/src/Mock/FileScenarioMock.Codeunit.al b/src/System Application/Test Library/File System/src/Mock/FileScenarioMock.Codeunit.al
index 8a29e86b79..b6afc6709e 100644
--- a/src/System Application/Test Library/File System/src/Mock/FileScenarioMock.Codeunit.al
+++ b/src/System Application/Test Library/File System/src/Mock/FileScenarioMock.Codeunit.al
@@ -28,5 +28,4 @@ codeunit 135811 "File Scenario Mock"
begin
Scenario.DeleteAll();
end;
-
}
\ No newline at end of file
diff --git a/src/System Application/Test Library/File System/src/Mock/FileSystemAccSelectionMock.Codeunit.al b/src/System Application/Test Library/File System/src/Mock/FileSystemAccSelectionMock.Codeunit.al
index 08ed37ef9c..f69d44a061 100644
--- a/src/System Application/Test Library/File System/src/Mock/FileSystemAccSelectionMock.Codeunit.al
+++ b/src/System Application/Test Library/File System/src/Mock/FileSystemAccSelectionMock.Codeunit.al
@@ -25,8 +25,8 @@ codeunit 135812 "File System Acc Selection Mock"
[EventSubscriber(ObjectType::Codeunit, Codeunit::"File Account Impl.", 'OnAfterSetSelectionFilter', '', false, false)]
local procedure SelectAccounts(var FileAccount: Record "File Account")
var
- SelectionFilter: Text;
AccountId: Guid;
+ SelectionFilter: Text;
begin
FileAccount.Reset();
diff --git a/src/System Application/Test Library/File System/src/TestFileAccount.Table.al b/src/System Application/Test Library/File System/src/TestFileAccount.Table.al
index a6734c7a76..c0320fe4ff 100644
--- a/src/System Application/Test Library/File System/src/TestFileAccount.Table.al
+++ b/src/System Application/Test Library/File System/src/TestFileAccount.Table.al
@@ -16,7 +16,6 @@ table 135810 "Test File Account"
{
Caption = 'Primary Key';
}
-
field(2; Name; Text[250])
{
Caption = 'Name';
diff --git a/src/System Application/Test Library/File System/src/TestFileSystemConnector.Codeunit.al b/src/System Application/Test Library/File System/src/TestFileSystemConnector.Codeunit.al
index 13fb9e282a..3f61f7e0e3 100644
--- a/src/System Application/Test Library/File System/src/TestFileSystemConnector.Codeunit.al
+++ b/src/System Application/Test Library/File System/src/TestFileSystemConnector.Codeunit.al
@@ -24,52 +24,42 @@ codeunit 135814 "Test File System Connector" implements "File System Connector"
procedure GetFile(AccountId: Guid; Path: Text; Stream: InStream);
begin
-
end;
procedure CreateFile(AccountId: Guid; Path: Text; Stream: InStream);
begin
-
end;
procedure CopyFile(AccountId: Guid; SourcePath: Text; TargetPath: Text);
begin
-
end;
procedure MoveFile(AccountId: Guid; SourcePath: Text; TargetPath: Text);
begin
-
end;
procedure FileExists(AccountId: Guid; Path: Text): Boolean;
begin
-
end;
procedure DeleteFile(AccountId: Guid; Path: Text);
begin
-
end;
procedure ListDirectories(AccountId: Guid; Path: Text; FilePaginationData: Codeunit "File Pagination Data"; var FileAccountContent: Record "File Account Content" temporary);
begin
-
end;
procedure CreateDirectory(AccountId: Guid; Path: Text);
begin
-
end;
procedure DirectoryExists(AccountId: Guid; Path: Text): Boolean;
begin
-
end;
procedure DeleteDirectory(AccountId: Guid; Path: Text);
begin
-
end;
procedure GetAccounts(var Accounts: Record "File Account")
@@ -108,7 +98,6 @@ codeunit 135814 "Test File System Connector" implements "File System Connector"
procedure GetLogoAsBase64(): Text
begin
-
end;
procedure GetDescription(): Text[250]
From ed3b04261e11185b0cd62047d9f887e5acf3c2fb Mon Sep 17 00:00:00 2001
From: Stefan Sosic
Date: Sat, 16 Nov 2024 17:23:17 +0100
Subject: [PATCH 40/43] Fix
---
.../Test/File System/src/FileAccountsTest.Codeunit.al | 2 +-
.../File System/src/FileScenarioPageTest.Codeunit.al | 4 +---
.../Test/File System/src/FileScenarioTest.Codeunit.al | 10 +++++-----
3 files changed, 7 insertions(+), 9 deletions(-)
diff --git a/src/System Application/Test/File System/src/FileAccountsTest.Codeunit.al b/src/System Application/Test/File System/src/FileAccountsTest.Codeunit.al
index cd111aea64..58657ff00c 100644
--- a/src/System Application/Test/File System/src/FileAccountsTest.Codeunit.al
+++ b/src/System Application/Test/File System/src/FileAccountsTest.Codeunit.al
@@ -165,8 +165,8 @@ codeunit 134750 "File Accounts Test"
[Test]
procedure IsAnyAccountRegisteredTest()
var
- FileConnectorMock: Codeunit "File Connector Mock";
FileAccount: Codeunit "File Account";
+ FileConnectorMock: Codeunit "File Connector Mock";
AccountId: Guid;
begin
// [SCENARIO] File Account Exists works as expected
diff --git a/src/System Application/Test/File System/src/FileScenarioPageTest.Codeunit.al b/src/System Application/Test/File System/src/FileScenarioPageTest.Codeunit.al
index 43c2fe0219..4328a0b6d8 100644
--- a/src/System Application/Test/File System/src/FileScenarioPageTest.Codeunit.al
+++ b/src/System Application/Test/File System/src/FileScenarioPageTest.Codeunit.al
@@ -15,13 +15,12 @@ codeunit 134751 "File Scenario Page Test"
Subtype = Test;
var
- Assert: Codeunit "Library Assert";
FileConnectorMock: Codeunit "File Connector Mock";
FileScenarioMock: Codeunit "File Scenario Mock";
+ Assert: Codeunit "Library Assert";
PermissionsMock: Codeunit "Permissions Mock";
DisplayNameTxt: Label '%1', Locked = true;
-
[Test]
[Scope('OnPrem')]
[TransactionModel(TransactionModel::AutoRollback)]
@@ -113,7 +112,6 @@ codeunit 134751 "File Scenario Page Test"
Assert.IsFalse(FileScenarioPage.Next(), 'There should not be another entry on the page');
end;
-
[Test]
[Scope('OnPrem')]
[TransactionModel(TransactionModel::AutoRollback)]
diff --git a/src/System Application/Test/File System/src/FileScenarioTest.Codeunit.al b/src/System Application/Test/File System/src/FileScenarioTest.Codeunit.al
index fcc5e035ce..f4cece8d13 100644
--- a/src/System Application/Test/File System/src/FileScenarioTest.Codeunit.al
+++ b/src/System Application/Test/File System/src/FileScenarioTest.Codeunit.al
@@ -15,11 +15,11 @@ codeunit 134752 "File Scenario Test"
Subtype = Test;
var
- Assert: Codeunit "Library Assert";
Any: Codeunit Any;
FileConnectorMock: Codeunit "File Connector Mock";
- FileScenarioMock: Codeunit "File Scenario Mock";
FileScenario: Codeunit "File Scenario";
+ FileScenarioMock: Codeunit "File Scenario Mock";
+ Assert: Codeunit "Library Assert";
PermissionsMock: Codeunit "Permissions Mock";
[Test]
@@ -157,8 +157,8 @@ codeunit 134752 "File Scenario Test"
procedure GetFileAccountDefaultDifferentNotExistTest()
var
FileAccount: Record "File Account";
- NonExistingAccountId: Guid;
DefaultAccountId: Guid;
+ NonExistingAccountId: Guid;
begin
// [Scenario] When the File scenario is mapped to a non-existing account and the default scenario is mapped to an existing accounts, GetFileAccount returns the correct account
PermissionsMock.Set('File System Admin');
@@ -253,14 +253,14 @@ codeunit 134752 "File Scenario Test"
[Scope('OnPrem')]
procedure UnassignScenarioTest()
var
- FileAccount: Record "File Account";
DefaultAccount: Record "File Account";
+ FileAccount: Record "File Account";
ResultAccount: Record "File Account";
begin
// [Scenario] When unassigning a scenario then it falls back to the default account.
PermissionsMock.Set('File System Admin');
- // [Given] Two accounts, one default and one not
+ // [Given] Two accounts, one default and one not
Initialize();
FileConnectorMock.AddAccount(FileAccount);
FileConnectorMock.AddAccount(DefaultAccount);
From 252a4b5bd668c70d08108d57ded1920350366a93 Mon Sep 17 00:00:00 2001
From: Stefan Sosic
Date: Sat, 16 Nov 2024 18:44:06 +0100
Subject: [PATCH 41/43] Improvements
---
.../src/Account/FileAccountImpl.Codeunit.al | 30 ++--
.../src/Account/FileAccountWizard.Page.al | 4 +-
.../src/Account/FileAccounts.Page.al | 8 +-
.../src/FileSystem/FileSystem.Codeunit.al | 2 +-
.../src/FileSystem/FileSystemImpl.Codeunit.al | 4 +-
.../src/Scenario/FileScenarioImpl.Codeunit.al | 162 +++++++++---------
...odeunit.al => FileScenarioMgt.Codeunit.al} | 2 +-
.../src/FileAccountsTest.Codeunit.al | 16 +-
.../src/FileScenarioTest.Codeunit.al | 38 ++--
9 files changed, 132 insertions(+), 134 deletions(-)
rename src/System Application/App/File System/src/Scenario/{FileScenario.Codeunit.al => FileScenarioMgt.Codeunit.al} (99%)
diff --git a/src/System Application/App/File System/src/Account/FileAccountImpl.Codeunit.al b/src/System Application/App/File System/src/Account/FileAccountImpl.Codeunit.al
index 2d285ed4a4..5487ce9cec 100644
--- a/src/System Application/App/File System/src/Account/FileAccountImpl.Codeunit.al
+++ b/src/System Application/App/File System/src/Account/FileAccountImpl.Codeunit.al
@@ -51,7 +51,7 @@ codeunit 9451 "File Account Impl."
var
CurrentDefaultFileAccount: Record "File Account";
ConfirmManagement: Codeunit "Confirm Management";
- FileScenario: Codeunit "File Scenario";
+ FileScenarioMgt: Codeunit "File Scenario Mgt.";
FileSystemConnector: Interface "File System Connector";
begin
CheckPermissions();
@@ -63,7 +63,7 @@ codeunit 9451 "File Account Impl."
exit;
// Get the current default account to track if it was deleted
- FileScenario.GetDefaultFileAccount(CurrentDefaultFileAccount);
+ FileScenarioMgt.GetDefaultFileAccount(CurrentDefaultFileAccount);
// Delete all selected accounts
repeat
@@ -82,7 +82,7 @@ codeunit 9451 "File Account Impl."
var
AllFileAccounts: Record "File Account";
NewDefaultFileAccount: Record "File Account";
- FileScenario: Codeunit "File Scenario";
+ FileScenarioMgt: Codeunit "File Scenario Mgt.";
begin
GetAllAccounts(false, AllFileAccounts);
@@ -102,7 +102,7 @@ codeunit 9451 "File Account Impl."
if PromptNewDefaultAccountChoice(NewDefaultFileAccount) then
MakeDefault(NewDefaultFileAccount)
else
- FileScenario.UnassignScenario(Enum::"File Scenario"::Default); // remove the default scenario as it is pointing to a non-existent account
+ FileScenarioMgt.UnassignScenario(Enum::"File Scenario"::Default); // remove the default scenario as it is pointing to a non-existent account
end;
local procedure PromptNewDefaultAccountChoice(var NewDefaultFileAccount: Record "File Account"): Boolean
@@ -120,9 +120,9 @@ codeunit 9451 "File Account Impl."
exit(false);
end;
- local procedure ImportLogo(var FileAccount: Record "File Account"; Connector: Interface "File System Connector")
+ local procedure ImportLogo(var FileAccount: Record "File Account"; FileSystemConnector: Interface "File System Connector")
var
- FileConnectorLogo: Record "File System Connector Logo";
+ FileSystemConnectorLogo: Record "File System Connector Logo";
Base64Convert: Codeunit "Base64 Convert";
TempBlob: Codeunit "Temp Blob";
InStream: InStream;
@@ -130,20 +130,20 @@ codeunit 9451 "File Account Impl."
OutStream: OutStream;
ConnectorLogoBase64: Text;
begin
- ConnectorLogoBase64 := Connector.GetLogoAsBase64();
+ ConnectorLogoBase64 := FileSystemConnector.GetLogoAsBase64();
if ConnectorLogoBase64 = '' then
exit;
- if not FileConnectorLogo.Get(FileAccount.Connector) then begin
+ if not FileSystemConnectorLogo.Get(FileAccount.Connector) then begin
TempBlob.CreateOutStream(OutStream);
Base64Convert.FromBase64(ConnectorLogoBase64, OutStream);
TempBlob.CreateInStream(InStream);
- FileConnectorLogo.Init();
- FileConnectorLogo.Connector := FileAccount.Connector;
- FileConnectorLogo.Logo.ImportStream(InStream, StrSubstNo(ConnectorLogoDescriptionTxt, FileAccount.Connector));
- if FileConnectorLogo.Insert() then;
+ FileSystemConnectorLogo.Init();
+ FileSystemConnectorLogo.Connector := FileAccount.Connector;
+ FileSystemConnectorLogo.Logo.ImportStream(InStream, StrSubstNo(ConnectorLogoDescriptionTxt, FileAccount.Connector));
+ if FileSystemConnectorLogo.Insert() then;
end;
- FileAccount.Logo := FileConnectorLogo.Logo;
+ FileAccount.Logo := FileSystemConnectorLogo.Logo;
end;
procedure IsAnyAccountRegistered(): Boolean
@@ -185,14 +185,14 @@ codeunit 9451 "File Account Impl."
procedure MakeDefault(var FileAccount: Record "File Account")
var
- FileScenario: Codeunit "File Scenario";
+ FileScenarioMgt: Codeunit "File Scenario Mgt.";
begin
CheckPermissions();
if IsNullGuid(FileAccount."Account Id") then
exit;
- FileScenario.SetDefaultFileAccount(FileAccount);
+ FileScenarioMgt.SetDefaultFileAccount(FileAccount);
end;
procedure BrowseAccount(var FileAccount: Record "File Account")
diff --git a/src/System Application/App/File System/src/Account/FileAccountWizard.Page.al b/src/System Application/App/File System/src/Account/FileAccountWizard.Page.al
index 100812085f..7c9bb670ee 100644
--- a/src/System Application/App/File System/src/Account/FileAccountWizard.Page.al
+++ b/src/System Application/App/File System/src/Account/FileAccountWizard.Page.al
@@ -325,7 +325,7 @@ page 9451 "File Account Wizard"
var
DefaultAccount: Record "File Account";
FileAccountImpl: Codeunit "File Account Impl.";
- FileScenario: Codeunit "File Scenario";
+ FileScenarioMgt: Codeunit "File Scenario Mgt.";
begin
FileAccountImpl.CheckPermissions();
@@ -337,7 +337,7 @@ page 9451 "File Account Wizard"
FileRateLimitDisplay := NoLimitTxt;
- if not FileScenario.GetDefaultFileAccount(DefaultAccount) then
+ if not FileScenarioMgt.GetDefaultFileAccount(DefaultAccount) then
SetAsDefault := true;
ConnectorsAvailable := Rec.FindFirst(); // Set the focus on the first record
diff --git a/src/System Application/App/File System/src/Account/FileAccounts.Page.al b/src/System Application/App/File System/src/Account/FileAccounts.Page.al
index 8a07f2596a..bf401f1440 100644
--- a/src/System Application/App/File System/src/Account/FileAccounts.Page.al
+++ b/src/System Application/App/File System/src/Account/FileAccounts.Page.al
@@ -253,7 +253,7 @@ page 9450 "File Accounts"
local procedure UpdateFileAccounts()
var
FileAccount: Codeunit "File Account";
- FileScenario: Codeunit "File Scenario";
+ FileScenarioMgt: Codeunit "File Scenario Mgt.";
IsSelected: Boolean;
SelectedAccountId: Guid;
begin
@@ -262,7 +262,7 @@ page 9450 "File Accounts"
IsSelected := not IsNullGuid(SelectedAccountId);
FileAccount.GetAllAccounts(true, Rec); // Refresh the file accounts
- FileScenario.GetDefaultFileAccount(DefaultFileAccount); // Refresh the default file account
+ FileScenarioMgt.GetDefaultFileAccount(DefaultFileAccount); // Refresh the default file account
if IsSelected then begin
Rec."Account Id" := SelectedAccountId;
@@ -279,9 +279,7 @@ page 9450 "File Accounts"
begin
UpdateAccounts := true;
-#pragma warning disable AL0603
- if not FileAccountImpl.IsValidConnector(Rec.Connector.AsInteger()) then
-#pragma warning restore AL0603
+ if not FileAccountImpl.IsValidConnector(Rec.Connector) then
Error(FileConnectorHasBeenUninstalledMsg);
Connector := Rec.Connector;
diff --git a/src/System Application/App/File System/src/FileSystem/FileSystem.Codeunit.al b/src/System Application/App/File System/src/FileSystem/FileSystem.Codeunit.al
index 6a46897536..e7d839d6cb 100644
--- a/src/System Application/App/File System/src/FileSystem/FileSystem.Codeunit.al
+++ b/src/System Application/App/File System/src/FileSystem/FileSystem.Codeunit.al
@@ -43,7 +43,7 @@ codeunit 9454 "File System"
end;
///
- /// Retireves a file from the file account.
+ /// Retrieves a file from the file account.
///
/// File Path to open.
/// Stream which contains the file content.
diff --git a/src/System Application/App/File System/src/FileSystem/FileSystemImpl.Codeunit.al b/src/System Application/App/File System/src/FileSystem/FileSystemImpl.Codeunit.al
index 16debc259e..0124f1e0a6 100644
--- a/src/System Application/App/File System/src/FileSystem/FileSystemImpl.Codeunit.al
+++ b/src/System Application/App/File System/src/FileSystem/FileSystemImpl.Codeunit.al
@@ -19,10 +19,10 @@ codeunit 9455 "File System Impl."
procedure Initialize(Scenario: Enum "File Scenario")
var
FileAccount: Record "File Account";
- FileScenario: Codeunit "File Scenario";
+ FileScenarioMgt: Codeunit "File Scenario Mgt.";
NoFileAccountFoundErr: Label 'No default file account defined.';
begin
- if not FileScenario.GetFileAccount(Scenario, FileAccount) then
+ if not FileScenarioMgt.GetFileAccount(Scenario, FileAccount) then
Error(NoFileAccountFoundErr);
Initialize(FileAccount);
diff --git a/src/System Application/App/File System/src/Scenario/FileScenarioImpl.Codeunit.al b/src/System Application/App/File System/src/Scenario/FileScenarioImpl.Codeunit.al
index 291638f58c..c5c0b14b6f 100644
--- a/src/System Application/App/File System/src/Scenario/FileScenarioImpl.Codeunit.al
+++ b/src/System Application/App/File System/src/Scenario/FileScenarioImpl.Codeunit.al
@@ -71,10 +71,10 @@ codeunit 9453 "File Scenario Impl."
/// The result of calling the function will be:
/// sales@cronus.com, "Sales Quote", "Sales Credit Memo", purchase@cronus.com, "Purchase Quote", "Purchase Invoice"
///
- /// A flattened tree structure representing all the file accounts and the scenarios assigned to them.
- procedure GetScenariosByFileAccount(var Result: Record "File Account Scenario")
+ /// A flattened tree structure representing all the file accounts and the scenarios assigned to them.
+ procedure GetScenariosByFileAccount(var FileAccountScenario: Record "File Account Scenario")
var
- DefaultAccount: Record "File Account";
+ DefaultFileAccount: Record "File Account";
FileAccounts: Record "File Account";
FileAccountScenarios: Record "File Account Scenario";
FileAccount: Codeunit "File Account";
@@ -82,8 +82,8 @@ codeunit 9453 "File Scenario Impl."
Position: Integer;
DisplayName: Text[2048];
begin
- Result.Reset();
- Result.DeleteAll();
+ FileAccountScenario.Reset();
+ FileAccountScenario.DeleteAll();
FileAccount.GetAllAccounts(FileAccounts);
@@ -92,14 +92,14 @@ codeunit 9453 "File Scenario Impl."
// The position is set in order to be able to properly sort the entries (by order of insertion)
Position := 1;
- GetDefaultAccount(DefaultAccount);
+ GetDefaultAccount(DefaultFileAccount);
repeat
- Default := (FileAccounts."Account Id" = DefaultAccount."Account Id") and (FileAccounts.Connector = DefaultAccount.Connector);
+ Default := (FileAccounts."Account Id" = DefaultFileAccount."Account Id") and (FileAccounts.Connector = DefaultFileAccount.Connector);
DisplayName := FileAccounts.Name;
// Add entry for the file account. Scenario is -1, because it isn't needed when displaying the file account.
- AddEntry(Result, Result.EntryType::Account, -1, FileAccounts."Account Id", FileAccounts.Connector, DisplayName, Default, Position);
+ AddEntry(FileAccountScenario, FileAccountScenario.EntryType::Account, -1, FileAccounts."Account Id", FileAccounts.Connector, DisplayName, Default, Position);
// Get the file scenarios assigned to the current file account, sorted by "Display Name"
GetFileScenariosForAccount(FileAccounts, FileAccountScenarios);
@@ -107,12 +107,12 @@ codeunit 9453 "File Scenario Impl."
if FileAccountScenarios.FindSet() then
repeat
// Add entry for every scenario that is assigned to the current file account
- AddEntry(Result, FileAccountScenarios.EntryType::Scenario, FileAccountScenarios.Scenario, FileAccountScenarios."Account Id", FileAccountScenarios.Connector, FileAccountScenarios."Display Name", false, Position);
+ AddEntry(FileAccountScenario, FileAccountScenarios.EntryType::Scenario, FileAccountScenarios.Scenario, FileAccountScenarios."Account Id", FileAccountScenarios.Connector, FileAccountScenarios."Display Name", false, Position);
until FileAccountScenarios.Next() = 0;
until FileAccounts.Next() = 0;
// Order by position to show accurate results
- Result.SetCurrentKey(Position);
+ FileAccountScenario.SetCurrentKey(Position);
end;
local procedure GetFileScenariosForAccount(FileAccount: Record "File Account"; var FileAccountScenarios: Record "File Account Scenario")
@@ -155,170 +155,170 @@ codeunit 9453 "File Scenario Impl."
FileAccountScenarios.SetCurrentKey("Display Name"); // sort scenarios by "Display Name"
end;
- local procedure AddEntry(var Result: Record "File Account Scenario"; EntryType: Option; Scenario: Integer; AccountId: Guid; Connector: Enum "File System Connector"; DisplayName: Text[2048]; Default: Boolean; var Position: Integer)
+ local procedure AddEntry(var FileAccountScenario: Record "File Account Scenario"; EntryType: Option; Scenario: Integer; AccountId: Guid; FileSystemConnector: Enum "File System Connector"; DisplayName: Text[2048]; Default: Boolean; var Position: Integer)
begin
- // Add entry to the result while maintaining the position so that the tree represents the data correctly
- Result.Init();
- Result.EntryType := EntryType;
- Result.Scenario := Scenario;
- Result."Account Id" := AccountId;
- Result.Connector := Connector;
- Result."Display Name" := DisplayName;
- Result.Default := Default;
- Result.Position := Position;
- Result.Insert();
+ // Add entry to the File Account Scenario while maintaining the position so that the tree represents the data correctly
+ FileAccountScenario.Init();
+ FileAccountScenario.EntryType := EntryType;
+ FileAccountScenario.Scenario := Scenario;
+ FileAccountScenario."Account Id" := AccountId;
+ FileAccountScenario.Connector := FileSystemConnector;
+ FileAccountScenario."Display Name" := DisplayName;
+ FileAccountScenario.Default := Default;
+ FileAccountScenario.Position := Position;
+ FileAccountScenario.Insert();
Position := Position + 1;
end;
- procedure AddScenarios(FileAccount: Record "File Account Scenario"): Boolean
+ procedure AddScenarios(FileAccountScenario: Record "File Account Scenario"): Boolean
var
- SelectedScenarios: Record "File Account Scenario";
+ SelectedFileAccScenarios: Record "File Account Scenario";
FileScenario: Record "File Scenario";
- ScenariosForAccount: Page "File Scenarios for Account";
+ FileScenariosForAccount: Page "File Scenarios for Account";
begin
FileAccountImpl.CheckPermissions();
- if FileAccount.EntryType <> FileAccount.EntryType::Account then // wrong entry, the entry should be of type "Account"
+ if FileAccountScenario.EntryType <> FileAccountScenario.EntryType::Account then // wrong entry, the entry should be of type "Account"
exit;
- ScenariosForAccount.Caption := StrSubstNo(ScenariosForAccountCaptionTxt, FileAccount."Display Name");
- ScenariosForAccount.LookupMode(true);
- ScenariosForAccount.SetRecord(FileAccount);
+ FileScenariosForAccount.Caption := StrSubstNo(ScenariosForAccountCaptionTxt, FileAccountScenario."Display Name");
+ FileScenariosForAccount.LookupMode(true);
+ FileScenariosForAccount.SetRecord(FileAccountScenario);
- if ScenariosForAccount.RunModal() <> Action::LookupOK then
+ if FileScenariosForAccount.RunModal() <> Action::LookupOK then
exit(false);
- ScenariosForAccount.GetSelectedScenarios(SelectedScenarios);
+ FileScenariosForAccount.GetSelectedScenarios(SelectedFileAccScenarios);
- if not SelectedScenarios.FindSet() then
+ if not SelectedFileAccScenarios.FindSet() then
exit(false);
repeat
- if not FileScenario.Get(SelectedScenarios.Scenario) then begin
- FileScenario."Account Id" := FileAccount."Account Id";
- FileScenario.Connector := FileAccount.Connector;
- FileScenario.Scenario := Enum::"File Scenario".FromInteger(SelectedScenarios.Scenario);
+ if not FileScenario.Get(SelectedFileAccScenarios.Scenario) then begin
+ FileScenario."Account Id" := FileAccountScenario."Account Id";
+ FileScenario.Connector := FileAccountScenario.Connector;
+ FileScenario.Scenario := Enum::"File Scenario".FromInteger(SelectedFileAccScenarios.Scenario);
FileScenario.Insert();
end else begin
- FileScenario."Account Id" := FileAccount."Account Id";
- FileScenario.Connector := FileAccount.Connector;
+ FileScenario."Account Id" := FileAccountScenario."Account Id";
+ FileScenario.Connector := FileAccountScenario.Connector;
FileScenario.Modify();
end;
- until SelectedScenarios.Next() = 0;
+ until SelectedFileAccScenarios.Next() = 0;
exit(true);
end;
- procedure GetAvailableScenariosForAccount(FileAccount: Record "File Account Scenario"; var FileScenarios: Record "File Account Scenario")
+ procedure GetAvailableScenariosForAccount(FileAccountScenario: Record "File Account Scenario"; var FileAccountScenarios: Record "File Account Scenario")
var
- Scenario: Record "File Scenario";
- FileScenario: Codeunit "File Scenario";
+ FileScenario: Record "File Scenario";
+ FileScenarioMgt: Codeunit "File Scenario Mgt.";
CurrentScenario, i : Integer;
IsAvailable: Boolean;
begin
- FileScenarios.Reset();
- FileScenarios.DeleteAll();
+ FileAccountScenarios.Reset();
+ FileAccountScenarios.DeleteAll();
i := 1;
foreach CurrentScenario in Enum::"File Scenario".Ordinals() do begin
- Clear(Scenario);
- Scenario.SetRange("Account Id", FileAccount."Account Id");
- Scenario.SetRange(Connector, FileAccount.Connector);
- Scenario.SetRange(Scenario, CurrentScenario);
+ Clear(FileScenario);
+ FileScenario.SetRange("Account Id", FileAccountScenarios."Account Id");
+ FileScenario.SetRange(Connector, FileAccountScenarios.Connector);
+ FileScenario.SetRange(Scenario, CurrentScenario);
// If the scenario isn't already connected to the file account, then it's available. Natually, we skip the default scenario
- IsAvailable := Scenario.IsEmpty() and (not (CurrentScenario = Enum::"File Scenario"::Default.AsInteger()));
+ IsAvailable := FileScenario.IsEmpty() and (not (CurrentScenario = Enum::"File Scenario"::Default.AsInteger()));
// If the scenario is available, allow partner to determine if it should be shown
if IsAvailable then
- FileScenario.OnBeforeInsertAvailableFileScenario(Enum::"File Scenario".FromInteger(CurrentScenario), IsAvailable);
+ FileScenarioMgt.OnBeforeInsertAvailableFileScenario(Enum::"File Scenario".FromInteger(CurrentScenario), IsAvailable);
if IsAvailable then begin
- FileScenarios."Account Id" := FileAccount."Account Id";
- FileScenarios.Connector := FileAccount.Connector;
- FileScenarios.Scenario := CurrentScenario;
- FileScenarios."Display Name" := Format(Enum::"File Scenario".FromInteger(Enum::"File Scenario".Ordinals().Get(i)));
+ FileAccountScenarios."Account Id" := FileAccountScenarios."Account Id";
+ FileAccountScenarios.Connector := FileAccountScenarios.Connector;
+ FileAccountScenarios.Scenario := CurrentScenario;
+ FileAccountScenarios."Display Name" := Format(Enum::"File Scenario".FromInteger(Enum::"File Scenario".Ordinals().Get(i)));
- FileScenarios.Insert();
+ FileAccountScenarios.Insert();
end;
i += 1;
end;
end;
- procedure ChangeAccount(var FileScenario: Record "File Account Scenario"): Boolean
+ procedure ChangeAccount(var FileAccountScenario: Record "File Account Scenario"): Boolean
var
- SelectedAccount: Record "File Account";
- Scenario: Record "File Scenario";
+ SelectedFileAccount: Record "File Account";
+ FileScenario: Record "File Scenario";
FileAccount: Codeunit "File Account";
AccountsPage: Page "File Accounts";
begin
FileAccountImpl.CheckPermissions();
- if not FileScenario.FindSet() then
+ if not FileAccountScenario.FindSet() then
exit(false);
- FileAccount.GetAllAccounts(false, SelectedAccount);
- if SelectedAccount.Get(FileScenario."Account Id", FileScenario.Connector) then;
+ FileAccount.GetAllAccounts(false, SelectedFileAccount);
+ if SelectedFileAccount.Get(FileAccountScenario."Account Id", FileAccountScenario.Connector) then;
AccountsPage.EnableLookupMode();
- AccountsPage.SetRecord(SelectedAccount);
+ AccountsPage.SetRecord(SelectedFileAccount);
AccountsPage.Caption := ChangeFileAccountForScenarioTxt;
if AccountsPage.RunModal() <> Action::LookupOK then
exit(false);
- AccountsPage.GetAccount(SelectedAccount);
+ AccountsPage.GetAccount(SelectedFileAccount);
- if IsNullGuid(SelectedAccount."Account Id") then // defensive check, no account was selected
+ if IsNullGuid(SelectedFileAccount."Account Id") then // defensive check, no account was selected
exit;
repeat
- if Scenario.Get(FileScenario.Scenario) then begin
- Scenario."Account Id" := SelectedAccount."Account Id";
- Scenario.Connector := SelectedAccount.Connector;
+ if FileScenario.Get(FileAccountScenario.Scenario) then begin
+ FileScenario."Account Id" := SelectedFileAccount."Account Id";
+ FileScenario.Connector := SelectedFileAccount.Connector;
- Scenario.Modify();
+ FileScenario.Modify();
end;
- until FileScenario.Next() = 0;
+ until FileAccountScenario.Next() = 0;
exit(true);
end;
- procedure DeleteScenario(var FileScenario: Record "File Account Scenario"): Boolean
+ procedure DeleteScenario(var FileAccountScenario: Record "File Account Scenario"): Boolean
var
- Scenario: Record "File Scenario";
+ FileScenario: Record "File Scenario";
begin
FileAccountImpl.CheckPermissions();
- if not FileScenario.FindSet() then
+ if not FileAccountScenario.FindSet() then
exit(false);
repeat
- if FileScenario.EntryType = FileScenario.EntryType::Scenario then begin
- Scenario.SetRange(Scenario, FileScenario.Scenario);
- Scenario.SetRange("Account Id", FileScenario."Account Id");
- Scenario.SetRange(Connector, FileScenario.Connector);
+ if FileAccountScenario.EntryType = FileAccountScenario.EntryType::Scenario then begin
+ FileScenario.SetRange(Scenario, FileAccountScenario.Scenario);
+ FileScenario.SetRange("Account Id", FileAccountScenario."Account Id");
+ FileScenario.SetRange(Connector, FileAccountScenario.Connector);
- Scenario.DeleteAll();
+ FileScenario.DeleteAll();
end;
- until FileScenario.Next() = 0;
+ until FileAccountScenario.Next() = 0;
exit(true);
end;
local procedure GetDefaultAccount(var FileAccount: Record "File Account")
var
- Scenario: Record "File Scenario";
+ FileScenario: Record "File Scenario";
begin
- if not Scenario.Get(Enum::"File Scenario"::Default) then
+ if not FileScenario.Get(Enum::"File Scenario"::Default) then
exit;
- FileAccount."Account Id" := Scenario."Account Id";
- FileAccount.Connector := Scenario.Connector;
+ FileAccount."Account Id" := FileScenario."Account Id";
+ FileAccount.Connector := FileScenario.Connector;
end;
var
diff --git a/src/System Application/App/File System/src/Scenario/FileScenario.Codeunit.al b/src/System Application/App/File System/src/Scenario/FileScenarioMgt.Codeunit.al
similarity index 99%
rename from src/System Application/App/File System/src/Scenario/FileScenario.Codeunit.al
rename to src/System Application/App/File System/src/Scenario/FileScenarioMgt.Codeunit.al
index 6bc25d5574..21e48ec781 100644
--- a/src/System Application/App/File System/src/Scenario/FileScenario.Codeunit.al
+++ b/src/System Application/App/File System/src/Scenario/FileScenarioMgt.Codeunit.al
@@ -8,7 +8,7 @@ namespace System.FileSystem;
///
/// Provides functionality to work with file scenarios.
///
-codeunit 9452 "File Scenario"
+codeunit 9452 "File Scenario Mgt."
{
InherentPermissions = X;
InherentEntitlements = X;
diff --git a/src/System Application/Test/File System/src/FileAccountsTest.Codeunit.al b/src/System Application/Test/File System/src/FileAccountsTest.Codeunit.al
index 58657ff00c..b26919336c 100644
--- a/src/System Application/Test/File System/src/FileAccountsTest.Codeunit.al
+++ b/src/System Application/Test/File System/src/FileAccountsTest.Codeunit.al
@@ -300,7 +300,7 @@ codeunit 134750 "File Accounts Test"
SecondAccount: Record "File Account";
FileConnectorMock: Codeunit "File Connector Mock";
FileAccountsSelectionMock: Codeunit "File System Acc Selection Mock";
- FileScenario: Codeunit "File Scenario";
+ FileScenarioMgt: Codeunit "File Scenario Mgt.";
FirstAccountId, ThirdAccountId : Guid;
FileAccountsTestPage: TestPage "File Accounts";
begin
@@ -314,7 +314,7 @@ codeunit 134750 "File Accounts Test"
FileConnectorMock.AddAccount(ThirdAccountId);
// [GIVEN] The second account is set as default
- FileScenario.SetDefaultFileAccount(SecondAccount);
+ FileScenarioMgt.SetDefaultFileAccount(SecondAccount);
// [WHEN] Open the File Accounts page
FileAccountsTestPage.OpenView();
@@ -343,7 +343,7 @@ codeunit 134750 "File Accounts Test"
SecondAccount: Record "File Account";
FileConnectorMock: Codeunit "File Connector Mock";
FileAccountsSelectionMock: Codeunit "File System Acc Selection Mock";
- FileScenario: Codeunit "File Scenario";
+ FileScenarioMgt: Codeunit "File Scenario Mgt.";
FirstAccountId, ThirdAccountId : Guid;
FileAccountsTestPage: TestPage "File Accounts";
begin
@@ -357,7 +357,7 @@ codeunit 134750 "File Accounts Test"
FileConnectorMock.AddAccount(ThirdAccountId);
// [GIVEN] The second account is set as default
- FileScenario.SetDefaultFileAccount(SecondAccount);
+ FileScenarioMgt.SetDefaultFileAccount(SecondAccount);
// [WHEN] Open the File Accounts page
FileAccountsTestPage.OpenView();
@@ -385,7 +385,7 @@ codeunit 134750 "File Accounts Test"
SecondAccount: Record "File Account";
FileConnectorMock: Codeunit "File Connector Mock";
FileAccountsSelectionMock: Codeunit "File System Acc Selection Mock";
- FileScenario: Codeunit "File Scenario";
+ FileScenarioMgt: Codeunit "File Scenario Mgt.";
FirstAccountId, ThirdAccountId : Guid;
FileAccountsTestPage: TestPage "File Accounts";
begin
@@ -399,7 +399,7 @@ codeunit 134750 "File Accounts Test"
FileConnectorMock.AddAccount(ThirdAccountId);
// [GIVEN] The second account is set as default
- FileScenario.SetDefaultFileAccount(SecondAccount);
+ FileScenarioMgt.SetDefaultFileAccount(SecondAccount);
// [WHEN] Open the File Accounts page
FileAccountsTestPage.OpenView();
@@ -429,7 +429,7 @@ codeunit 134750 "File Accounts Test"
SecondAccount: Record "File Account";
FileConnectorMock: Codeunit "File Connector Mock";
FileAccountsSelectionMock: Codeunit "File System Acc Selection Mock";
- FileScenario: Codeunit "File Scenario";
+ FileScenarioMgt: Codeunit "File Scenario Mgt.";
FirstAccountId, ThirdAccountId : Guid;
FileAccountsTestPage: TestPage "File Accounts";
begin
@@ -443,7 +443,7 @@ codeunit 134750 "File Accounts Test"
FileConnectorMock.AddAccount(ThirdAccountId);
// [GIVEN] The second account is set as default
- FileScenario.SetDefaultFileAccount(SecondAccount);
+ FileScenarioMgt.SetDefaultFileAccount(SecondAccount);
// [WHEN] Open the File Accounts page
FileAccountsTestPage.OpenView();
diff --git a/src/System Application/Test/File System/src/FileScenarioTest.Codeunit.al b/src/System Application/Test/File System/src/FileScenarioTest.Codeunit.al
index f4cece8d13..bee1a0a475 100644
--- a/src/System Application/Test/File System/src/FileScenarioTest.Codeunit.al
+++ b/src/System Application/Test/File System/src/FileScenarioTest.Codeunit.al
@@ -17,7 +17,7 @@ codeunit 134752 "File Scenario Test"
var
Any: Codeunit Any;
FileConnectorMock: Codeunit "File Connector Mock";
- FileScenario: Codeunit "File Scenario";
+ FileScenarioMgt: Codeunit "File Scenario Mgt.";
FileScenarioMock: Codeunit "File Scenario Mock";
Assert: Codeunit "Library Assert";
PermissionsMock: Codeunit "Permissions Mock";
@@ -36,7 +36,7 @@ codeunit 134752 "File Scenario Test"
// [When] calling GetFileAccount
// [Then] false is returned
- Assert.IsFalse(FileScenario.GetFileAccount(Enum::"File Scenario"::"Test File Scenario", FileAccount), 'There should not be any account');
+ Assert.IsFalse(FileScenarioMgt.GetFileAccount(Enum::"File Scenario"::"Test File Scenario", FileAccount), 'There should not be any account');
end;
[Test]
@@ -56,7 +56,7 @@ codeunit 134752 "File Scenario Test"
// [When] calling GetFileAccount
// [Then] false is returned
- Assert.IsFalse(FileScenario.GetFileAccount(Enum::"File Scenario"::"Test File Scenario", FileAccount), 'There should not be any account mapped to the scenario');
+ Assert.IsFalse(FileScenarioMgt.GetFileAccount(Enum::"File Scenario"::"Test File Scenario", FileAccount), 'There should not be any account mapped to the scenario');
end;
[Test]
@@ -76,7 +76,7 @@ codeunit 134752 "File Scenario Test"
// [When] calling GetFileAccount
// [Then] false is returned
- Assert.IsFalse(FileScenario.GetFileAccount(Enum::"File Scenario"::"Test File Scenario", FileAccount), 'There should not be any account mapped to the scenario');
+ Assert.IsFalse(FileScenarioMgt.GetFileAccount(Enum::"File Scenario"::"Test File Scenario", FileAccount), 'There should not be any account mapped to the scenario');
end;
[Test]
@@ -96,7 +96,7 @@ codeunit 134752 "File Scenario Test"
// [When] calling GetFileAccount
// [Then] true is returned and the File account is as expected
- Assert.IsTrue(FileScenario.GetFileAccount(Enum::"File Scenario"::"Test File Scenario", FileAccount), 'There should be an File account');
+ Assert.IsTrue(FileScenarioMgt.GetFileAccount(Enum::"File Scenario"::"Test File Scenario", FileAccount), 'There should be an File account');
Assert.AreEqual(AccountId, FileAccount."Account Id", 'Wrong account ID');
Assert.AreEqual(Enum::"File System Connector"::"Test File System Connector", FileAccount.Connector, 'Wrong connector');
end;
@@ -118,7 +118,7 @@ codeunit 134752 "File Scenario Test"
// [When] calling GetFileAccount
// [Then] true is returned and the File account is as expected
- Assert.IsTrue(FileScenario.GetFileAccount(Enum::"File Scenario"::"Test File Scenario", FileAccount), 'There should be an File account');
+ Assert.IsTrue(FileScenarioMgt.GetFileAccount(Enum::"File Scenario"::"Test File Scenario", FileAccount), 'There should be an File account');
Assert.AreEqual(AccountId, FileAccount."Account Id", 'Wrong account ID');
Assert.AreEqual(Enum::"File System Connector"::"Test File System Connector", FileAccount.Connector, 'Wrong connector');
end;
@@ -143,11 +143,11 @@ codeunit 134752 "File Scenario Test"
// [When] calling GetFileAccount
// [Then] true is returned and the File accounts are as expected
- Assert.IsTrue(FileScenario.GetFileAccount(Enum::"File Scenario"::"Test File Scenario", FileAccount), 'There should be an File account');
+ Assert.IsTrue(FileScenarioMgt.GetFileAccount(Enum::"File Scenario"::"Test File Scenario", FileAccount), 'There should be an File account');
Assert.AreEqual(AccountId, FileAccount."Account Id", 'Wrong account ID');
Assert.AreEqual(Enum::"File System Connector"::"Test File System Connector", FileAccount.Connector, 'Wrong connector');
- Assert.IsTrue(FileScenario.GetFileAccount(Enum::"File Scenario"::Default, FileAccount), 'There should be an File account');
+ Assert.IsTrue(FileScenarioMgt.GetFileAccount(Enum::"File Scenario"::Default, FileAccount), 'There should be an File account');
Assert.AreEqual(DefaultAccountId, FileAccount."Account Id", 'Wrong account ID');
Assert.AreEqual(Enum::"File System Connector"::"Test File System Connector", FileAccount.Connector, 'Wrong connector');
end;
@@ -172,11 +172,11 @@ codeunit 134752 "File Scenario Test"
// [When] calling GetFileAccount
// [Then] true is returned and the File accounts are as expected
- Assert.IsTrue(FileScenario.GetFileAccount(Enum::"File Scenario"::"Test File Scenario", FileAccount), 'There should be an File account');
+ Assert.IsTrue(FileScenarioMgt.GetFileAccount(Enum::"File Scenario"::"Test File Scenario", FileAccount), 'There should be an File account');
Assert.AreEqual(DefaultAccountId, FileAccount."Account Id", 'Wrong account ID');
Assert.AreEqual(Enum::"File System Connector"::"Test File System Connector", FileAccount.Connector, 'Wrong connector');
- Assert.IsTrue(FileScenario.GetFileAccount(Enum::"File Scenario"::Default, FileAccount), 'There should be an File account for the default scenario');
+ Assert.IsTrue(FileScenarioMgt.GetFileAccount(Enum::"File Scenario"::Default, FileAccount), 'There should be an File account for the default scenario');
Assert.AreEqual(DefaultAccountId, FileAccount."Account Id", 'Wrong default account ID');
Assert.AreEqual(Enum::"File System Connector"::"Test File System Connector", FileAccount.Connector, 'Wrong default account connector');
end;
@@ -201,12 +201,12 @@ codeunit 134752 "File Scenario Test"
// [When] calling GetFileAccount
// [Then] true is returned and the File account is as expected
- Assert.IsTrue(FileScenario.GetFileAccount(Enum::"File Scenario"::"Test File Scenario", FileAccount), 'There should be an File account');
+ Assert.IsTrue(FileScenarioMgt.GetFileAccount(Enum::"File Scenario"::"Test File Scenario", FileAccount), 'There should be an File account');
Assert.AreEqual(AccountId, FileAccount."Account Id", 'Wrong account ID');
Assert.AreEqual(Enum::"File System Connector"::"Test File System Connector", FileAccount.Connector, 'Wrong connector');
// [Then] there's no account for the default File scenario
- Assert.IsFalse(FileScenario.GetFileAccount(Enum::"File Scenario"::Default, FileAccount), 'There should not be an File account for the default scenario');
+ Assert.IsFalse(FileScenarioMgt.GetFileAccount(Enum::"File Scenario"::Default, FileAccount), 'There should not be an File account for the default scenario');
end;
[Test]
@@ -230,7 +230,7 @@ codeunit 134752 "File Scenario Test"
Scenario := Scenario::Default;
// [When] Setting the File account for the scenario
- FileScenario.SetFileAccount(Scenario, FileAccount);
+ FileScenarioMgt.SetFileAccount(Scenario, FileAccount);
// [Then] The scenario exists and is as expected
Assert.IsTrue(FileSystemTestLib.GetFileScenarioAccountIdAndFileConnector(Scenario, AccountId, FileSystemConnector), 'The File scenario should exist');
@@ -241,7 +241,7 @@ codeunit 134752 "File Scenario Test"
AnotherAccount.Connector := Enum::"File System Connector"::"Test File System Connector";
// [When] Setting overwriting the File account for the scenario
- FileScenario.SetFileAccount(Scenario, AnotherAccount);
+ FileScenarioMgt.SetFileAccount(Scenario, AnotherAccount);
// [Then] The scenario still exists and is as expected
Assert.IsTrue(FileSystemTestLib.GetFileScenarioAccountIdAndFileConnector(Scenario, AccountId, FileSystemConnector), 'The File scenario should exist');
@@ -264,18 +264,18 @@ codeunit 134752 "File Scenario Test"
Initialize();
FileConnectorMock.AddAccount(FileAccount);
FileConnectorMock.AddAccount(DefaultAccount);
- FileScenario.SetDefaultFileAccount(DefaultAccount);
- FileScenario.SetFileAccount(Enum::"File Scenario"::"Test File Scenario", FileAccount);
+ FileScenarioMgt.SetDefaultFileAccount(DefaultAccount);
+ FileScenarioMgt.SetFileAccount(Enum::"File Scenario"::"Test File Scenario", FileAccount);
// mid-test verification
- FileScenario.GetFileAccount(Enum::"File Scenario"::"Test File Scenario", ResultAccount);
+ FileScenarioMgt.GetFileAccount(Enum::"File Scenario"::"Test File Scenario", ResultAccount);
Assert.AreEqual(FileAccount."Account Id", ResultAccount."Account Id", 'Wrong account');
// [When] Unassign the File scenario
- FileScenario.UnassignScenario(Enum::"File Scenario"::"Test File Scenario");
+ FileScenarioMgt.UnassignScenario(Enum::"File Scenario"::"Test File Scenario");
// [Then] The default account is returned for that account
- FileScenario.GetFileAccount(Enum::"File Scenario"::"Test File Scenario", ResultAccount);
+ FileScenarioMgt.GetFileAccount(Enum::"File Scenario"::"Test File Scenario", ResultAccount);
Assert.AreEqual(DefaultAccount."Account Id", ResultAccount."Account Id", 'The default account should have been returned');
end;
From b3bb20dd3a79654438d91a6f1ebb8db3355db74b Mon Sep 17 00:00:00 2001
From: Thomas Williamson
Date: Sat, 16 Nov 2024 19:38:55 +0100
Subject: [PATCH 42/43] Revert renaming of codeunit "File Scenario"
---
.../src/Account/FileAccountImpl.Codeunit.al | 12 +++---
.../src/Account/FileAccountWizard.Page.al | 4 +-
.../src/Account/FileAccounts.Page.al | 4 +-
.../src/FileSystem/FileSystemImpl.Codeunit.al | 2 +-
...t.Codeunit.al => FileScenario.Codeunit.al} | 2 +-
.../src/Scenario/FileScenarioImpl.Codeunit.al | 16 ++++----
.../src/FileAccountsTest.Codeunit.al | 16 ++++----
.../src/FileScenarioTest.Codeunit.al | 38 +++++++++----------
8 files changed, 47 insertions(+), 47 deletions(-)
rename src/System Application/App/File System/src/Scenario/{FileScenarioMgt.Codeunit.al => FileScenario.Codeunit.al} (99%)
diff --git a/src/System Application/App/File System/src/Account/FileAccountImpl.Codeunit.al b/src/System Application/App/File System/src/Account/FileAccountImpl.Codeunit.al
index 5487ce9cec..4cf2e575be 100644
--- a/src/System Application/App/File System/src/Account/FileAccountImpl.Codeunit.al
+++ b/src/System Application/App/File System/src/Account/FileAccountImpl.Codeunit.al
@@ -51,7 +51,7 @@ codeunit 9451 "File Account Impl."
var
CurrentDefaultFileAccount: Record "File Account";
ConfirmManagement: Codeunit "Confirm Management";
- FileScenarioMgt: Codeunit "File Scenario Mgt.";
+ FileScenario: Codeunit "File Scenario";
FileSystemConnector: Interface "File System Connector";
begin
CheckPermissions();
@@ -63,7 +63,7 @@ codeunit 9451 "File Account Impl."
exit;
// Get the current default account to track if it was deleted
- FileScenarioMgt.GetDefaultFileAccount(CurrentDefaultFileAccount);
+ FileScenario.GetDefaultFileAccount(CurrentDefaultFileAccount);
// Delete all selected accounts
repeat
@@ -82,7 +82,7 @@ codeunit 9451 "File Account Impl."
var
AllFileAccounts: Record "File Account";
NewDefaultFileAccount: Record "File Account";
- FileScenarioMgt: Codeunit "File Scenario Mgt.";
+ FileScenario: Codeunit "File Scenario";
begin
GetAllAccounts(false, AllFileAccounts);
@@ -102,7 +102,7 @@ codeunit 9451 "File Account Impl."
if PromptNewDefaultAccountChoice(NewDefaultFileAccount) then
MakeDefault(NewDefaultFileAccount)
else
- FileScenarioMgt.UnassignScenario(Enum::"File Scenario"::Default); // remove the default scenario as it is pointing to a non-existent account
+ FileScenario.UnassignScenario(Enum::"File Scenario"::Default); // remove the default scenario as it is pointing to a non-existent account
end;
local procedure PromptNewDefaultAccountChoice(var NewDefaultFileAccount: Record "File Account"): Boolean
@@ -185,14 +185,14 @@ codeunit 9451 "File Account Impl."
procedure MakeDefault(var FileAccount: Record "File Account")
var
- FileScenarioMgt: Codeunit "File Scenario Mgt.";
+ FileScenario: Codeunit "File Scenario";
begin
CheckPermissions();
if IsNullGuid(FileAccount."Account Id") then
exit;
- FileScenarioMgt.SetDefaultFileAccount(FileAccount);
+ FileScenario.SetDefaultFileAccount(FileAccount);
end;
procedure BrowseAccount(var FileAccount: Record "File Account")
diff --git a/src/System Application/App/File System/src/Account/FileAccountWizard.Page.al b/src/System Application/App/File System/src/Account/FileAccountWizard.Page.al
index 7c9bb670ee..100812085f 100644
--- a/src/System Application/App/File System/src/Account/FileAccountWizard.Page.al
+++ b/src/System Application/App/File System/src/Account/FileAccountWizard.Page.al
@@ -325,7 +325,7 @@ page 9451 "File Account Wizard"
var
DefaultAccount: Record "File Account";
FileAccountImpl: Codeunit "File Account Impl.";
- FileScenarioMgt: Codeunit "File Scenario Mgt.";
+ FileScenario: Codeunit "File Scenario";
begin
FileAccountImpl.CheckPermissions();
@@ -337,7 +337,7 @@ page 9451 "File Account Wizard"
FileRateLimitDisplay := NoLimitTxt;
- if not FileScenarioMgt.GetDefaultFileAccount(DefaultAccount) then
+ if not FileScenario.GetDefaultFileAccount(DefaultAccount) then
SetAsDefault := true;
ConnectorsAvailable := Rec.FindFirst(); // Set the focus on the first record
diff --git a/src/System Application/App/File System/src/Account/FileAccounts.Page.al b/src/System Application/App/File System/src/Account/FileAccounts.Page.al
index bf401f1440..98d953065c 100644
--- a/src/System Application/App/File System/src/Account/FileAccounts.Page.al
+++ b/src/System Application/App/File System/src/Account/FileAccounts.Page.al
@@ -253,7 +253,7 @@ page 9450 "File Accounts"
local procedure UpdateFileAccounts()
var
FileAccount: Codeunit "File Account";
- FileScenarioMgt: Codeunit "File Scenario Mgt.";
+ FileScenario: Codeunit "File Scenario";
IsSelected: Boolean;
SelectedAccountId: Guid;
begin
@@ -262,7 +262,7 @@ page 9450 "File Accounts"
IsSelected := not IsNullGuid(SelectedAccountId);
FileAccount.GetAllAccounts(true, Rec); // Refresh the file accounts
- FileScenarioMgt.GetDefaultFileAccount(DefaultFileAccount); // Refresh the default file account
+ FileScenario.GetDefaultFileAccount(DefaultFileAccount); // Refresh the default file account
if IsSelected then begin
Rec."Account Id" := SelectedAccountId;
diff --git a/src/System Application/App/File System/src/FileSystem/FileSystemImpl.Codeunit.al b/src/System Application/App/File System/src/FileSystem/FileSystemImpl.Codeunit.al
index 0124f1e0a6..df08d1d5be 100644
--- a/src/System Application/App/File System/src/FileSystem/FileSystemImpl.Codeunit.al
+++ b/src/System Application/App/File System/src/FileSystem/FileSystemImpl.Codeunit.al
@@ -19,7 +19,7 @@ codeunit 9455 "File System Impl."
procedure Initialize(Scenario: Enum "File Scenario")
var
FileAccount: Record "File Account";
- FileScenarioMgt: Codeunit "File Scenario Mgt.";
+ FileScenarioMgt: Codeunit "File Scenario";
NoFileAccountFoundErr: Label 'No default file account defined.';
begin
if not FileScenarioMgt.GetFileAccount(Scenario, FileAccount) then
diff --git a/src/System Application/App/File System/src/Scenario/FileScenarioMgt.Codeunit.al b/src/System Application/App/File System/src/Scenario/FileScenario.Codeunit.al
similarity index 99%
rename from src/System Application/App/File System/src/Scenario/FileScenarioMgt.Codeunit.al
rename to src/System Application/App/File System/src/Scenario/FileScenario.Codeunit.al
index 21e48ec781..6bc25d5574 100644
--- a/src/System Application/App/File System/src/Scenario/FileScenarioMgt.Codeunit.al
+++ b/src/System Application/App/File System/src/Scenario/FileScenario.Codeunit.al
@@ -8,7 +8,7 @@ namespace System.FileSystem;
///
/// Provides functionality to work with file scenarios.
///
-codeunit 9452 "File Scenario Mgt."
+codeunit 9452 "File Scenario"
{
InherentPermissions = X;
InherentEntitlements = X;
diff --git a/src/System Application/App/File System/src/Scenario/FileScenarioImpl.Codeunit.al b/src/System Application/App/File System/src/Scenario/FileScenarioImpl.Codeunit.al
index c5c0b14b6f..99206aa62b 100644
--- a/src/System Application/App/File System/src/Scenario/FileScenarioImpl.Codeunit.al
+++ b/src/System Application/App/File System/src/Scenario/FileScenarioImpl.Codeunit.al
@@ -214,8 +214,8 @@ codeunit 9453 "File Scenario Impl."
procedure GetAvailableScenariosForAccount(FileAccountScenario: Record "File Account Scenario"; var FileAccountScenarios: Record "File Account Scenario")
var
- FileScenario: Record "File Scenario";
- FileScenarioMgt: Codeunit "File Scenario Mgt.";
+ Scenario: Record "File Scenario";
+ FileScenario: Codeunit "File Scenario";
CurrentScenario, i : Integer;
IsAvailable: Boolean;
begin
@@ -224,17 +224,17 @@ codeunit 9453 "File Scenario Impl."
i := 1;
foreach CurrentScenario in Enum::"File Scenario".Ordinals() do begin
- Clear(FileScenario);
- FileScenario.SetRange("Account Id", FileAccountScenarios."Account Id");
- FileScenario.SetRange(Connector, FileAccountScenarios.Connector);
- FileScenario.SetRange(Scenario, CurrentScenario);
+ Clear(Scenario);
+ Scenario.SetRange("Account Id", FileAccountScenarios."Account Id");
+ Scenario.SetRange(Connector, FileAccountScenarios.Connector);
+ Scenario.SetRange(Scenario, CurrentScenario);
// If the scenario isn't already connected to the file account, then it's available. Natually, we skip the default scenario
- IsAvailable := FileScenario.IsEmpty() and (not (CurrentScenario = Enum::"File Scenario"::Default.AsInteger()));
+ IsAvailable := Scenario.IsEmpty() and (not (CurrentScenario = Enum::"File Scenario"::Default.AsInteger()));
// If the scenario is available, allow partner to determine if it should be shown
if IsAvailable then
- FileScenarioMgt.OnBeforeInsertAvailableFileScenario(Enum::"File Scenario".FromInteger(CurrentScenario), IsAvailable);
+ FileScenario.OnBeforeInsertAvailableFileScenario(Enum::"File Scenario".FromInteger(CurrentScenario), IsAvailable);
if IsAvailable then begin
FileAccountScenarios."Account Id" := FileAccountScenarios."Account Id";
diff --git a/src/System Application/Test/File System/src/FileAccountsTest.Codeunit.al b/src/System Application/Test/File System/src/FileAccountsTest.Codeunit.al
index b26919336c..58657ff00c 100644
--- a/src/System Application/Test/File System/src/FileAccountsTest.Codeunit.al
+++ b/src/System Application/Test/File System/src/FileAccountsTest.Codeunit.al
@@ -300,7 +300,7 @@ codeunit 134750 "File Accounts Test"
SecondAccount: Record "File Account";
FileConnectorMock: Codeunit "File Connector Mock";
FileAccountsSelectionMock: Codeunit "File System Acc Selection Mock";
- FileScenarioMgt: Codeunit "File Scenario Mgt.";
+ FileScenario: Codeunit "File Scenario";
FirstAccountId, ThirdAccountId : Guid;
FileAccountsTestPage: TestPage "File Accounts";
begin
@@ -314,7 +314,7 @@ codeunit 134750 "File Accounts Test"
FileConnectorMock.AddAccount(ThirdAccountId);
// [GIVEN] The second account is set as default
- FileScenarioMgt.SetDefaultFileAccount(SecondAccount);
+ FileScenario.SetDefaultFileAccount(SecondAccount);
// [WHEN] Open the File Accounts page
FileAccountsTestPage.OpenView();
@@ -343,7 +343,7 @@ codeunit 134750 "File Accounts Test"
SecondAccount: Record "File Account";
FileConnectorMock: Codeunit "File Connector Mock";
FileAccountsSelectionMock: Codeunit "File System Acc Selection Mock";
- FileScenarioMgt: Codeunit "File Scenario Mgt.";
+ FileScenario: Codeunit "File Scenario";
FirstAccountId, ThirdAccountId : Guid;
FileAccountsTestPage: TestPage "File Accounts";
begin
@@ -357,7 +357,7 @@ codeunit 134750 "File Accounts Test"
FileConnectorMock.AddAccount(ThirdAccountId);
// [GIVEN] The second account is set as default
- FileScenarioMgt.SetDefaultFileAccount(SecondAccount);
+ FileScenario.SetDefaultFileAccount(SecondAccount);
// [WHEN] Open the File Accounts page
FileAccountsTestPage.OpenView();
@@ -385,7 +385,7 @@ codeunit 134750 "File Accounts Test"
SecondAccount: Record "File Account";
FileConnectorMock: Codeunit "File Connector Mock";
FileAccountsSelectionMock: Codeunit "File System Acc Selection Mock";
- FileScenarioMgt: Codeunit "File Scenario Mgt.";
+ FileScenario: Codeunit "File Scenario";
FirstAccountId, ThirdAccountId : Guid;
FileAccountsTestPage: TestPage "File Accounts";
begin
@@ -399,7 +399,7 @@ codeunit 134750 "File Accounts Test"
FileConnectorMock.AddAccount(ThirdAccountId);
// [GIVEN] The second account is set as default
- FileScenarioMgt.SetDefaultFileAccount(SecondAccount);
+ FileScenario.SetDefaultFileAccount(SecondAccount);
// [WHEN] Open the File Accounts page
FileAccountsTestPage.OpenView();
@@ -429,7 +429,7 @@ codeunit 134750 "File Accounts Test"
SecondAccount: Record "File Account";
FileConnectorMock: Codeunit "File Connector Mock";
FileAccountsSelectionMock: Codeunit "File System Acc Selection Mock";
- FileScenarioMgt: Codeunit "File Scenario Mgt.";
+ FileScenario: Codeunit "File Scenario";
FirstAccountId, ThirdAccountId : Guid;
FileAccountsTestPage: TestPage "File Accounts";
begin
@@ -443,7 +443,7 @@ codeunit 134750 "File Accounts Test"
FileConnectorMock.AddAccount(ThirdAccountId);
// [GIVEN] The second account is set as default
- FileScenarioMgt.SetDefaultFileAccount(SecondAccount);
+ FileScenario.SetDefaultFileAccount(SecondAccount);
// [WHEN] Open the File Accounts page
FileAccountsTestPage.OpenView();
diff --git a/src/System Application/Test/File System/src/FileScenarioTest.Codeunit.al b/src/System Application/Test/File System/src/FileScenarioTest.Codeunit.al
index bee1a0a475..f4cece8d13 100644
--- a/src/System Application/Test/File System/src/FileScenarioTest.Codeunit.al
+++ b/src/System Application/Test/File System/src/FileScenarioTest.Codeunit.al
@@ -17,7 +17,7 @@ codeunit 134752 "File Scenario Test"
var
Any: Codeunit Any;
FileConnectorMock: Codeunit "File Connector Mock";
- FileScenarioMgt: Codeunit "File Scenario Mgt.";
+ FileScenario: Codeunit "File Scenario";
FileScenarioMock: Codeunit "File Scenario Mock";
Assert: Codeunit "Library Assert";
PermissionsMock: Codeunit "Permissions Mock";
@@ -36,7 +36,7 @@ codeunit 134752 "File Scenario Test"
// [When] calling GetFileAccount
// [Then] false is returned
- Assert.IsFalse(FileScenarioMgt.GetFileAccount(Enum::"File Scenario"::"Test File Scenario", FileAccount), 'There should not be any account');
+ Assert.IsFalse(FileScenario.GetFileAccount(Enum::"File Scenario"::"Test File Scenario", FileAccount), 'There should not be any account');
end;
[Test]
@@ -56,7 +56,7 @@ codeunit 134752 "File Scenario Test"
// [When] calling GetFileAccount
// [Then] false is returned
- Assert.IsFalse(FileScenarioMgt.GetFileAccount(Enum::"File Scenario"::"Test File Scenario", FileAccount), 'There should not be any account mapped to the scenario');
+ Assert.IsFalse(FileScenario.GetFileAccount(Enum::"File Scenario"::"Test File Scenario", FileAccount), 'There should not be any account mapped to the scenario');
end;
[Test]
@@ -76,7 +76,7 @@ codeunit 134752 "File Scenario Test"
// [When] calling GetFileAccount
// [Then] false is returned
- Assert.IsFalse(FileScenarioMgt.GetFileAccount(Enum::"File Scenario"::"Test File Scenario", FileAccount), 'There should not be any account mapped to the scenario');
+ Assert.IsFalse(FileScenario.GetFileAccount(Enum::"File Scenario"::"Test File Scenario", FileAccount), 'There should not be any account mapped to the scenario');
end;
[Test]
@@ -96,7 +96,7 @@ codeunit 134752 "File Scenario Test"
// [When] calling GetFileAccount
// [Then] true is returned and the File account is as expected
- Assert.IsTrue(FileScenarioMgt.GetFileAccount(Enum::"File Scenario"::"Test File Scenario", FileAccount), 'There should be an File account');
+ Assert.IsTrue(FileScenario.GetFileAccount(Enum::"File Scenario"::"Test File Scenario", FileAccount), 'There should be an File account');
Assert.AreEqual(AccountId, FileAccount."Account Id", 'Wrong account ID');
Assert.AreEqual(Enum::"File System Connector"::"Test File System Connector", FileAccount.Connector, 'Wrong connector');
end;
@@ -118,7 +118,7 @@ codeunit 134752 "File Scenario Test"
// [When] calling GetFileAccount
// [Then] true is returned and the File account is as expected
- Assert.IsTrue(FileScenarioMgt.GetFileAccount(Enum::"File Scenario"::"Test File Scenario", FileAccount), 'There should be an File account');
+ Assert.IsTrue(FileScenario.GetFileAccount(Enum::"File Scenario"::"Test File Scenario", FileAccount), 'There should be an File account');
Assert.AreEqual(AccountId, FileAccount."Account Id", 'Wrong account ID');
Assert.AreEqual(Enum::"File System Connector"::"Test File System Connector", FileAccount.Connector, 'Wrong connector');
end;
@@ -143,11 +143,11 @@ codeunit 134752 "File Scenario Test"
// [When] calling GetFileAccount
// [Then] true is returned and the File accounts are as expected
- Assert.IsTrue(FileScenarioMgt.GetFileAccount(Enum::"File Scenario"::"Test File Scenario", FileAccount), 'There should be an File account');
+ Assert.IsTrue(FileScenario.GetFileAccount(Enum::"File Scenario"::"Test File Scenario", FileAccount), 'There should be an File account');
Assert.AreEqual(AccountId, FileAccount."Account Id", 'Wrong account ID');
Assert.AreEqual(Enum::"File System Connector"::"Test File System Connector", FileAccount.Connector, 'Wrong connector');
- Assert.IsTrue(FileScenarioMgt.GetFileAccount(Enum::"File Scenario"::Default, FileAccount), 'There should be an File account');
+ Assert.IsTrue(FileScenario.GetFileAccount(Enum::"File Scenario"::Default, FileAccount), 'There should be an File account');
Assert.AreEqual(DefaultAccountId, FileAccount."Account Id", 'Wrong account ID');
Assert.AreEqual(Enum::"File System Connector"::"Test File System Connector", FileAccount.Connector, 'Wrong connector');
end;
@@ -172,11 +172,11 @@ codeunit 134752 "File Scenario Test"
// [When] calling GetFileAccount
// [Then] true is returned and the File accounts are as expected
- Assert.IsTrue(FileScenarioMgt.GetFileAccount(Enum::"File Scenario"::"Test File Scenario", FileAccount), 'There should be an File account');
+ Assert.IsTrue(FileScenario.GetFileAccount(Enum::"File Scenario"::"Test File Scenario", FileAccount), 'There should be an File account');
Assert.AreEqual(DefaultAccountId, FileAccount."Account Id", 'Wrong account ID');
Assert.AreEqual(Enum::"File System Connector"::"Test File System Connector", FileAccount.Connector, 'Wrong connector');
- Assert.IsTrue(FileScenarioMgt.GetFileAccount(Enum::"File Scenario"::Default, FileAccount), 'There should be an File account for the default scenario');
+ Assert.IsTrue(FileScenario.GetFileAccount(Enum::"File Scenario"::Default, FileAccount), 'There should be an File account for the default scenario');
Assert.AreEqual(DefaultAccountId, FileAccount."Account Id", 'Wrong default account ID');
Assert.AreEqual(Enum::"File System Connector"::"Test File System Connector", FileAccount.Connector, 'Wrong default account connector');
end;
@@ -201,12 +201,12 @@ codeunit 134752 "File Scenario Test"
// [When] calling GetFileAccount
// [Then] true is returned and the File account is as expected
- Assert.IsTrue(FileScenarioMgt.GetFileAccount(Enum::"File Scenario"::"Test File Scenario", FileAccount), 'There should be an File account');
+ Assert.IsTrue(FileScenario.GetFileAccount(Enum::"File Scenario"::"Test File Scenario", FileAccount), 'There should be an File account');
Assert.AreEqual(AccountId, FileAccount."Account Id", 'Wrong account ID');
Assert.AreEqual(Enum::"File System Connector"::"Test File System Connector", FileAccount.Connector, 'Wrong connector');
// [Then] there's no account for the default File scenario
- Assert.IsFalse(FileScenarioMgt.GetFileAccount(Enum::"File Scenario"::Default, FileAccount), 'There should not be an File account for the default scenario');
+ Assert.IsFalse(FileScenario.GetFileAccount(Enum::"File Scenario"::Default, FileAccount), 'There should not be an File account for the default scenario');
end;
[Test]
@@ -230,7 +230,7 @@ codeunit 134752 "File Scenario Test"
Scenario := Scenario::Default;
// [When] Setting the File account for the scenario
- FileScenarioMgt.SetFileAccount(Scenario, FileAccount);
+ FileScenario.SetFileAccount(Scenario, FileAccount);
// [Then] The scenario exists and is as expected
Assert.IsTrue(FileSystemTestLib.GetFileScenarioAccountIdAndFileConnector(Scenario, AccountId, FileSystemConnector), 'The File scenario should exist');
@@ -241,7 +241,7 @@ codeunit 134752 "File Scenario Test"
AnotherAccount.Connector := Enum::"File System Connector"::"Test File System Connector";
// [When] Setting overwriting the File account for the scenario
- FileScenarioMgt.SetFileAccount(Scenario, AnotherAccount);
+ FileScenario.SetFileAccount(Scenario, AnotherAccount);
// [Then] The scenario still exists and is as expected
Assert.IsTrue(FileSystemTestLib.GetFileScenarioAccountIdAndFileConnector(Scenario, AccountId, FileSystemConnector), 'The File scenario should exist');
@@ -264,18 +264,18 @@ codeunit 134752 "File Scenario Test"
Initialize();
FileConnectorMock.AddAccount(FileAccount);
FileConnectorMock.AddAccount(DefaultAccount);
- FileScenarioMgt.SetDefaultFileAccount(DefaultAccount);
- FileScenarioMgt.SetFileAccount(Enum::"File Scenario"::"Test File Scenario", FileAccount);
+ FileScenario.SetDefaultFileAccount(DefaultAccount);
+ FileScenario.SetFileAccount(Enum::"File Scenario"::"Test File Scenario", FileAccount);
// mid-test verification
- FileScenarioMgt.GetFileAccount(Enum::"File Scenario"::"Test File Scenario", ResultAccount);
+ FileScenario.GetFileAccount(Enum::"File Scenario"::"Test File Scenario", ResultAccount);
Assert.AreEqual(FileAccount."Account Id", ResultAccount."Account Id", 'Wrong account');
// [When] Unassign the File scenario
- FileScenarioMgt.UnassignScenario(Enum::"File Scenario"::"Test File Scenario");
+ FileScenario.UnassignScenario(Enum::"File Scenario"::"Test File Scenario");
// [Then] The default account is returned for that account
- FileScenarioMgt.GetFileAccount(Enum::"File Scenario"::"Test File Scenario", ResultAccount);
+ FileScenario.GetFileAccount(Enum::"File Scenario"::"Test File Scenario", ResultAccount);
Assert.AreEqual(DefaultAccount."Account Id", ResultAccount."Account Id", 'The default account should have been returned');
end;
From ba7e6e8d4523796f977e67a0b22f2094e7ae2472 Mon Sep 17 00:00:00 2001
From: Thomas Williamson
Date: Sat, 16 Nov 2024 20:22:30 +0100
Subject: [PATCH 43/43] Add review suggestions from StefanSosic
---
.../App/File System/src/Account/FileAccountImpl.Codeunit.al | 2 +-
.../App/File System/src/Account/FileAccounts.Page.al | 6 +-----
2 files changed, 2 insertions(+), 6 deletions(-)
diff --git a/src/System Application/App/File System/src/Account/FileAccountImpl.Codeunit.al b/src/System Application/App/File System/src/Account/FileAccountImpl.Codeunit.al
index 4cf2e575be..1bc722a651 100644
--- a/src/System Application/App/File System/src/Account/FileAccountImpl.Codeunit.al
+++ b/src/System Application/App/File System/src/Account/FileAccountImpl.Codeunit.al
@@ -39,7 +39,7 @@ codeunit 9451 "File Account Impl."
if LoadLogos then
ImportLogo(TempFileAccount, Connector);
- if not TempFileAccount.Insert() then;
+ TempFileAccount.Insert();
until FileAccounts.Next() = 0;
end;
diff --git a/src/System Application/App/File System/src/Account/FileAccounts.Page.al b/src/System Application/App/File System/src/Account/FileAccounts.Page.al
index 98d953065c..d4a1c8ab39 100644
--- a/src/System Application/App/File System/src/Account/FileAccounts.Page.al
+++ b/src/System Application/App/File System/src/Account/FileAccounts.Page.al
@@ -34,13 +34,11 @@ page 9450 "File Accounts"
{
repeater(Accounts)
{
- Visible = ShowLogo;
FreezeColumn = NameField;
field(LogoField; Rec.Logo)
{
ShowCaption = false;
Caption = ' ';
- Visible = ShowLogo;
ToolTip = 'Specifies the logo for the type of file account.';
Width = 1;
}
@@ -228,11 +226,10 @@ page 9450 "File Accounts"
var
FeatureTelemetry: Codeunit "Feature Telemetry";
begin
- FeatureTelemetry.LogUptake('0000CTA', 'Fileing', Enum::"Feature Uptake Status"::Discovered);
+ FeatureTelemetry.LogUptake('0000CTA', 'File System', Enum::"Feature Uptake Status"::Discovered);
CanUserManageFileSetup := FileAccountImpl.IsUserFileAdmin();
Rec.SetCurrentKey("Account Id", Connector);
UpdateFileAccounts();
- ShowLogo := true;
end;
trigger OnAfterGetRecord()
@@ -319,7 +316,6 @@ page 9450 "File Accounts"
CanUserManageFileSetup: Boolean;
IsDefault: Boolean;
IsInLookupMode: Boolean;
- ShowLogo: Boolean;
UpdateAccounts: Boolean;
FileConnectorHasBeenUninstalledMsg: Label 'The selected file extension has been uninstalled. To view information about the file account, you must reinstall the extension.';
DefaultTxt: Text;