diff --git a/Apps/W1/EDocumentConnectors/SignUp/app/app.json b/Apps/W1/EDocumentConnectors/SignUp/app/app.json index 5d02eb4470..2e3e8b9e5d 100644 --- a/Apps/W1/EDocumentConnectors/SignUp/app/app.json +++ b/Apps/W1/EDocumentConnectors/SignUp/app/app.json @@ -1,46 +1,46 @@ { - "id": "b56171bd-9a8e-47ad-a527-99f476d5af83", - "name": "E-Document Connector - SignUp", - "publisher": "Microsoft", - "brief": "E-Document Connector - SignUp", - "description": "E-Document Connector - SignUp", - "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=2204541", - "url": "https://go.microsoft.com/fwlink/?LinkId=724011", - "logo": "ExtensionLogo.png", - "contextSensitiveHelpUrl": "https://go.microsoft.com/fwlink/?linkid=2206603", - "dependencies": [ - { - "id": "e1d97edc-c239-46b4-8d84-6368bdf67c8b", - "name": "E-Document Core", - "publisher": "Microsoft", - "version": "26.0.0.0" - }, - { - "id": "d852a468-263e-49e5-bfda-f09e33342b89", - "name": "E-Documents Connector with External Endpoints", - "publisher": "Microsoft", - "version": "26.0.0.0" - } - ], + "id": "b56171bd-9a8e-47ad-a527-99f476d5af83", + "name": "E-Document Connector - SignUp", + "publisher": "Microsoft", + "brief": "E-Document Connector - SignUp", + "description": "E-Document Connector - SignUp", + "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=2204541", + "url": "https://go.microsoft.com/fwlink/?LinkId=724011", + "logo": "ExtensionLogo.png", + "contextSensitiveHelpUrl": "https://go.microsoft.com/fwlink/?linkid=2206603", + "dependencies": [ + { + "id": "e1d97edc-c239-46b4-8d84-6368bdf67c8b", + "name": "E-Document Core", + "publisher": "Microsoft", + "version": "26.0.0.0" + }, + { + "id": "d852a468-263e-49e5-bfda-f09e33342b89", + "name": "E-Documents Connector with External Endpoints", + "publisher": "Microsoft", + "version": "26.0.0.0" + } + ], "internalsVisibleTo": [], - "screenshots": [], - "platform": "26.0.0.0", - "idRanges": [ - { - "from": 6380, - "to": 6389 - } - ], - "resourceExposurePolicy": { - "allowDebugging": true, - "allowDownloadingSource": true, - "includeSourceInSymbolFile": true - }, - "application": "26.0.0.0", - "target": "OnPrem", + "screenshots": [], + "platform": "26.0.0.0", + "idRanges": [ + { + "from": 6380, + "to": 6389 + } + ], + "resourceExposurePolicy": { + "allowDebugging": true, + "allowDownloadingSource": true, + "includeSourceInSymbolFile": true + }, + "application": "26.0.0.0", + "target": "OnPrem", "features": [ "TranslationFile" ] diff --git a/Apps/W1/EDocumentConnectors/SignUp/test/ExtensionLogo.png b/Apps/W1/EDocumentConnectors/SignUp/test/ExtensionLogo.png new file mode 100644 index 0000000000..4d2c9a626c Binary files /dev/null and b/Apps/W1/EDocumentConnectors/SignUp/test/ExtensionLogo.png differ diff --git a/Apps/W1/EDocumentConnectors/SignUp/test/app.json b/Apps/W1/EDocumentConnectors/SignUp/test/app.json new file mode 100644 index 0000000000..a244074d48 --- /dev/null +++ b/Apps/W1/EDocumentConnectors/SignUp/test/app.json @@ -0,0 +1,113 @@ +{ + "id": "b56171bd-9a8e-47ad-a527-99f476d5af83", + "name": "E-Document Connector - SignUp Tests", + "publisher": "Microsoft", + "brief": "E-Document Connector - SignUp Tests", + "description": "E-Document Connector - SignUp Tests", + "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=2204541", + "url": "https://go.microsoft.com/fwlink/?LinkId=724011", + "logo": "ExtensionLogo.png", + "contextSensitiveHelpUrl": "https://go.microsoft.com/fwlink/?linkid=2206603", + "dependencies": [ + { + "id": "b56171bd-9a8e-47ad-a527-99f476d5af83", + "name": "E-Document Connector - SignUp", + "publisher": "SignUp Software AB", + "version": "26.0.0.0" + }, + { + "id": "e1d97edc-c239-46b4-8d84-6368bdf67c8b", + "name": "E-Document Core", + "publisher": "Microsoft", + "version": "26.0.0.0" + }, + { + "id": "de0dddf3-9917-430d-8d20-6e7679a08500", + "name": "E-Document Core Demo Data", + "publisher": "Microsoft", + "version": "26.0.0.0" + }, + { + "id": "5a0b41e9-7a42-4123-d521-2265186cfb31", + "name": "Contoso Coffee Demo Dataset", + "publisher": "Microsoft", + "version": "26.0.0.0" + }, + { + "id": "e1d97edc-c239-46b4-8d84-6368bdf67c8c", + "name": "E-Document Core Tests", + "publisher": "Microsoft", + "version": "26.0.0.0" + }, + { + "id": "dd0be2ea-f733-4d65-bb34-a28f4624fb14", + "name": "Library Assert", + "publisher": "Microsoft", + "version": "26.0.0.0" + }, + { + "id": "e7320ebb-08b3-4406-b1ec-b4927d3e280b", + "name": "Any", + "publisher": "Microsoft", + "version": "26.0.0.0" + }, + { + "id": "5d86850b-0d76-4eca-bd7b-951ad998e997", + "name": "Tests-TestLibraries", + "publisher": "Microsoft", + "version": "26.0.0.0" + }, + { + "id": "9856ae4f-d1a7-46ef-89bb-6ef056398228", + "name": "System Application Test Library", + "publisher": "Microsoft", + "version": "26.0.0.0" + }, + { + "id": "23de40a6-dfe8-4f80-80db-d70f83ce8caf", + "name": "Test Runner", + "publisher": "Microsoft", + "version": "26.0.0.0" + }, + { + "id": "5095f467-0a01-4b99-99d1-9ff1237d286f", + "name": "Library Variable Storage", + "publisher": "Microsoft", + "version": "26.0.0.0" + }, + { + "id": "bee8cf2f-494a-42f4-aabd-650e87934d39", + "name": "Business Foundation Test Libraries", + "publisher": "Microsoft", + "version": "26.0.0.0" + }, + { + "id": "40860557-a18d-42ad-aecb-22b7dd80dc80", + "name": "Permissions Mock", + "publisher": "Microsoft", + "version": "26.0.0.0" + } + ], + "screenshots": [], + "platform": "26.0.0.0", + "application": "26.0.0.0", + "idRanges": [ + { + "from": 148195, + "to": 148199 + } + ], + "resourceExposurePolicy": { + "allowDebugging": true, + "allowDownloadingSource": true, + "includeSourceInSymbolFile": true + }, + "runtime": "15.0", + "features": [ + "TranslationFile" + ], + "target": "OnPrem" +} \ No newline at end of file diff --git a/Apps/W1/EDocumentConnectors/SignUp/test/src/IntegrationEvents.Codeunit.al b/Apps/W1/EDocumentConnectors/SignUp/test/src/IntegrationEvents.Codeunit.al new file mode 100644 index 0000000000..6708ef7364 --- /dev/null +++ b/Apps/W1/EDocumentConnectors/SignUp/test/src/IntegrationEvents.Codeunit.al @@ -0,0 +1,27 @@ +namespace Microsoft.EServices.EDocumentConnector.SignUp; + + +codeunit 148197 IntegrationEvents +{ + EventSubscriberInstance = Manual; + + var + LibraryLowerPermissions: Codeunit "Library - Lower Permissions"; + IntegrationHelpers: Codeunit IntegrationHelpers; + + [EventSubscriber(ObjectType::Codeunit, Codeunit::Processing, OnBeforeGetTargetDocumentRequest, '', true, true)] + local procedure ProcessingOnBeforeGetTargetDocumentRequest() + begin + this.LibraryLowerPermissions.AddPermissionSet('SignUpEDCOEdit'); + this.IntegrationHelpers.SetAPICode('/signup/200/download'); + this.LibraryLowerPermissions.AddPermissionSet('SignUpEDCORead'); + end; + + [EventSubscriber(ObjectType::Codeunit, Codeunit::Processing, OnBeforeGetTargetDocumentRequest, '', true, true)] + local procedure ProcessingOnBeforeMarkFetched() + begin + this.LibraryLowerPermissions.AddPermissionSet('SignUpEDCOEdit'); + this.IntegrationHelpers.SetAPICode('/signup/200/markdownloaded'); + this.LibraryLowerPermissions.AddPermissionSet('SignUpEDCORead'); + end; +} \ No newline at end of file diff --git a/Apps/W1/EDocumentConnectors/SignUp/test/src/IntegrationHelpers.Codeunit.al b/Apps/W1/EDocumentConnectors/SignUp/test/src/IntegrationHelpers.Codeunit.al new file mode 100644 index 0000000000..427b124aa3 --- /dev/null +++ b/Apps/W1/EDocumentConnectors/SignUp/test/src/IntegrationHelpers.Codeunit.al @@ -0,0 +1,67 @@ +namespace Microsoft.EServices.EDocumentConnector.SignUp; + + +codeunit 148196 IntegrationHelpers +{ + internal procedure SetAPIWith200Code() + begin + this.SetAPICode('/signup/200'); + end; + + internal procedure SetAPIWith500Code() + begin + this.SetAPICode('/signup/500'); + end; + + internal procedure SetAPICode(Path: Text) + var + ConnectionSetup: Record ConnectionSetup; + begin + ConnectionSetup.Get(); + ConnectionSetup."Service URL" := this.SetMockServiceUrl(Path); + ConnectionSetup.Modify(true); + end; + + internal procedure SetCommonConnectionSetup() + var + ConnectionSetup: Record ConnectionSetup; + Authentication: Codeunit Authentication; + begin + ConnectionSetup.Get(); + Authentication.StorageSet(ConnectionSetup."Root App ID", this.DummyId()); + Authentication.StorageSet(ConnectionSetup."Root Secret", this.DummyId()); + Authentication.StorageSet(ConnectionSetup."Root Tenant", this.DummyId()); + Authentication.StorageSet(ConnectionSetup."Client ID", this.DummyId()); + Authentication.StorageSet(ConnectionSetup."Client Secret", this.DummyId()); + Authentication.StorageSet(ConnectionSetup."Client Tenant", this.ClientTenantId()); + + ConnectionSetup."Authentication URL" := this.SetMockServiceUrl('/%1/oauth2/token'); + ConnectionSetup."Environment Type" := ConnectionSetup."Environment Type"::Test; + ConnectionSetup.Modify(true); + end; + + internal procedure SetMockServiceUrl(Path: Text): Text[250] + begin + exit('http://localhost:8080' + Path); + end; + + local procedure ClientTenantId(): Text + begin + exit('signup'); + end; + + local procedure DummyId(): Text[100] + begin + exit('0a4b7f70-452a-4883-844f-296443704124'); + end; + + internal procedure MockServiceDocumentId(): Text + begin + exit('485959a5-4a96-4a41-a208-13c30bb7e4d3'); + end; + + internal procedure MockCompanyId(): Text[100] + begin + exit('0007:SIGNUPSOFTWARE'); + end; +} \ No newline at end of file diff --git a/Apps/W1/EDocumentConnectors/SignUp/test/src/IntegrationTests.Codeunit.al b/Apps/W1/EDocumentConnectors/SignUp/test/src/IntegrationTests.Codeunit.al new file mode 100644 index 0000000000..1df14aaed1 --- /dev/null +++ b/Apps/W1/EDocumentConnectors/SignUp/test/src/IntegrationTests.Codeunit.al @@ -0,0 +1,633 @@ +// ------------------------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// ------------------------------------------------------------------------------------------------ +namespace Microsoft.EServices.EDocumentConnector.SignUp; + + +using Microsoft.eServices.EDocument; +using Microsoft.Inventory.Item; +using Microsoft.EServices.EDocument.Service.Participant; +using Microsoft.Foundation.Company; +//using Microsoft.Purchases.Document; +using Microsoft.Purchases.Vendor; +using Microsoft.Sales.Customer; +using System.Threading; +using Microsoft.eServices.EDocument.Integration; + +codeunit 148195 IntegrationTests +{ + Subtype = Test; + + Permissions = tabledata ConnectionSetup = rimd, + tabledata "E-Document" = r; + + var + Customer: Record Customer; + Vendor: Record Vendor; + Item: Record Item; + EDocumentService: Record "E-Document Service"; + LibraryEDocument: Codeunit "Library - E-Document"; + LibraryInventory: Codeunit "Library - Inventory"; + LibraryLowerPermissions: Codeunit "Library - Lower Permissions"; + LibraryJobQueue: Codeunit "Library - Job Queue"; + IntegrationHelpers: Codeunit IntegrationHelpers; + Assert: Codeunit Assert; + IsInitialized: Boolean; + IncorrectValueErr: Label 'Wrong value', Locked = true; + + /// + /// Test needs MockService running to work. + /// + [Test] + [HandlerFunctions('ExternalHttpRequestHandler')] + procedure SubmitDocument() + var + EDocument: Record "E-Document"; + JobQueueEntry: Record "Job Queue Entry"; + EDocumentPage: TestPage "E-Document"; + EDocLogList: List of [Enum "E-Document Service Status"]; + begin + // Steps: + // Pending response -> Sent + this.Initialize(); + + // [Given] Team member + this.LibraryLowerPermissions.SetTeamMember(); + this.LibraryLowerPermissions.AddPermissionSet('SignUpEDCORead'); + + // [When] Posting invoice and EDocument is created + this.LibraryEDocument.PostInvoice(this.Customer); + EDocument.FindLast(); + this.LibraryEDocument.RunEDocumentJobQueue(EDocument); + + // [When] EDocument is fetched after running ExFlow SubmitDocument + EDocument.FindLast(); + + // [Then] Document Id has been correctly set on E-Document, parsed from Integration response. + this.Assert.AreEqual(this.IntegrationHelpers.MockServiceDocumentId(), EDocument."Signup Document Id", 'ExFlow integration failed to set Document Id on E-Document'); + this.Assert.AreEqual(Enum::"E-Document Status"::"In Progress", EDocument.Status, 'E-Document should be set to in progress'); + + // [THEN] Open E-Document page + EDocumentPage.OpenView(); + EDocumentPage.GoToRecord(EDocument); + this.Assert.AreEqual(Format(EDocument.Direction::Outgoing), EDocumentPage.Direction.Value(), this.IncorrectValueErr); + this.Assert.AreEqual(EDocument."Document No.", EDocumentPage."Document No.".Value(), this.IncorrectValueErr); + + // [THEN] E-Document Service Status has "Pending Response" + this.Assert.AreEqual(this.EDocumentService.Code, EDocumentPage.EdocoumentServiceStatus."E-Document Service Code".Value(), this.IncorrectValueErr); + this.Assert.AreEqual(Format(Enum::"E-Document Service Status"::"Pending Response"), EDocumentPage.EdocoumentServiceStatus.Status.Value(), this.IncorrectValueErr); + this.Assert.AreEqual('2', EDocumentPage.EdocoumentServiceStatus.Logs.Value(), this.IncorrectValueErr); + + Clear(EDocLogList); + EDocLogList.Add(Enum::"E-Document Service Status"::"Exported"); + EDocLogList.Add(Enum::"E-Document Service Status"::"Pending Response"); + this.LibraryEDocument.AssertEDocumentLogs(EDocument, this.EDocumentService, EDocLogList); + + // [THEN] E-Document Errors and Warnings has correct status + this.Assert.AreEqual('', EDocumentPage.ErrorMessagesPart."Message Type".Value(), this.IncorrectValueErr); + this.Assert.AreEqual('', EDocumentPage.ErrorMessagesPart.Description.Value(), this.IncorrectValueErr); + EDocumentPage.Close(); + + // [WHEN] Executing Get Response succesfully + JobQueueEntry.FindJobQueueEntry(JobQueueEntry."Object Type to Run"::Codeunit, Codeunit::"E-Document Get Response"); + this.LibraryJobQueue.RunJobQueueDispatcher(JobQueueEntry); + + // [When] EDocument is fetched after running ExFlow GetResponse + EDocument.FindLast(); + + // [Then] E-Document is considered processed + this.Assert.AreEqual(Enum::"E-Document Status"::"In Progress", EDocument.Status, 'E-Document should be set to in progress'); + + // [THEN] Open E-Document page + EDocumentPage.OpenView(); + EDocumentPage.GoToRecord(EDocument); + this.Assert.AreEqual(Format(EDocument.Direction::Outgoing), EDocumentPage.Direction.Value(), this.IncorrectValueErr); + this.Assert.AreEqual(EDocument."Document No.", EDocumentPage."Document No.".Value(), this.IncorrectValueErr); + + // [THEN] E-Document Service Status has Sent + this.Assert.AreEqual(this.EDocumentService.Code, EDocumentPage.EdocoumentServiceStatus."E-Document Service Code".Value(), this.IncorrectValueErr); + this.Assert.AreEqual(Format(Enum::"E-Document Service Status"::"Pending Response"), EDocumentPage.EdocoumentServiceStatus.Status.Value(), this.IncorrectValueErr); + this.Assert.AreEqual('3', EDocumentPage.EdocoumentServiceStatus.Logs.Value(), this.IncorrectValueErr); + + Clear(EDocLogList); + EDocLogList.Add(Enum::"E-Document Service Status"::"Exported"); + EDocLogList.Add(Enum::"E-Document Service Status"::"Pending Response"); + EDocLogList.Add(Enum::"E-Document Service Status"::"Pending Response"); + this.LibraryEDocument.AssertEDocumentLogs(EDocument, this.EDocumentService, EDocLogList); + + // [THEN] E-Document Errors and Warnings has correct status + this.Assert.AreEqual('', EDocumentPage.ErrorMessagesPart."Message Type".Value(), this.IncorrectValueErr); + this.Assert.AreEqual('', EDocumentPage.ErrorMessagesPart.Description.Value(), this.IncorrectValueErr); + EDocumentPage.Close(); + end; + + /// + /// Test needs MockService running to work. + /// + [Test] + procedure SubmitDocument_Pending_Sent() + var + EDocument: Record "E-Document"; + JobQueueEntry: Record "Job Queue Entry"; + EDocumentPage: TestPage "E-Document"; + EDocLogList: List of [Enum "E-Document Service Status"]; + begin + // Steps: + // Pending response -> Pending response -> Sent + this.Initialize(); + this.IntegrationHelpers.SetAPIWith200Code(); + + // [Given] Team member + this.LibraryLowerPermissions.SetTeamMember(); + this.LibraryLowerPermissions.AddPermissionSet('SignUpEDCORead'); + + // [When] Posting invoice and EDocument is created + this.LibraryEDocument.PostInvoice(this.Customer); + EDocument.FindLast(); + this.LibraryEDocument.RunEDocumentJobQueue(EDocument); + + // [When] EDocument is fetched after running ExFlow SubmitDocument + EDocument.FindLast(); + + // [Then] Document Id has been correctly set on E-Document, parsed from Integration response + this.Assert.AreEqual(this.IntegrationHelpers.MockServiceDocumentId(), EDocument."Signup Document Id", 'ExFlow integration failed to set Document Id on E-Document'); + + // [Then] E-Document is pending response as ExFlow is async + this.Assert.AreEqual(Enum::"E-Document Status"::"In Progress", EDocument.Status, 'E-Document should be set to in progress'); + + // [THEN] Open E-Document page + EDocumentPage.OpenView(); + EDocumentPage.GoToRecord(EDocument); + this.Assert.AreEqual(Format(EDocument.Direction::Outgoing), EDocumentPage.Direction.Value(), this.IncorrectValueErr); + this.Assert.AreEqual(EDocument."Document No.", EDocumentPage."Document No.".Value(), this.IncorrectValueErr); + + // [THEN] E-Document Service Status has pending response + this.Assert.AreEqual(this.EDocumentService.Code, EDocumentPage.EdocoumentServiceStatus."E-Document Service Code".Value(), this.IncorrectValueErr); + this.Assert.AreEqual(Format(Enum::"E-Document Service Status"::"Pending Response"), EDocumentPage.EdocoumentServiceStatus.Status.Value(), this.IncorrectValueErr); + this.Assert.AreEqual('2', EDocumentPage.EdocoumentServiceStatus.Logs.Value(), this.IncorrectValueErr); + Clear(EDocLogList); + EDocLogList.Add(Enum::"E-Document Service Status"::"Exported"); + EDocLogList.Add(Enum::"E-Document Service Status"::"Pending Response"); + this.LibraryEDocument.AssertEDocumentLogs(EDocument, this.EDocumentService, EDocLogList); + + // [THEN] E-Document Errors and Warnings has correct status + this.Assert.AreEqual('', EDocumentPage.ErrorMessagesPart."Message Type".Value(), this.IncorrectValueErr); + this.Assert.AreEqual('', EDocumentPage.ErrorMessagesPart.Description.Value(), this.IncorrectValueErr); + EDocumentPage.Close(); + + // [WHEN] Executing Get Response succesfully + this.LibraryLowerPermissions.AddPermissionSet('SignUpEDCOEdit'); + this.IntegrationHelpers.SetAPICode('/signup/200/response-pending'); + this.LibraryLowerPermissions.AddPermissionSet('SignUpEDCORead'); + JobQueueEntry.FindJobQueueEntry(JobQueueEntry."Object Type to Run"::Codeunit, Codeunit::"E-Document Get Response"); + this.LibraryJobQueue.RunJobQueueDispatcher(JobQueueEntry); + + // [When] EDocument is fetched after running ExFlow GetResponse + EDocument.FindLast(); + + // [Then] E-Document is pending response as ExFlow is async + this.Assert.AreEqual(Enum::"E-Document Status"::"In Progress", EDocument.Status, 'E-Document should be set to in progress'); + + // [THEN] Open E-Document page + EDocumentPage.OpenView(); + EDocumentPage.GoToRecord(EDocument); + this.Assert.AreEqual(Format(EDocument.Direction::Outgoing), EDocumentPage.Direction.Value(), this.IncorrectValueErr); + this.Assert.AreEqual(EDocument."Document No.", EDocumentPage."Document No.".Value(), this.IncorrectValueErr); + + // [THEN] E-Document Service Status has pending response + this.Assert.AreEqual(this.EDocumentService.Code, EDocumentPage.EdocoumentServiceStatus."E-Document Service Code".Value(), this.IncorrectValueErr); + this.Assert.AreEqual(Format(Enum::"E-Document Service Status"::"Pending Response"), EDocumentPage.EdocoumentServiceStatus.Status.Value(), this.IncorrectValueErr); + this.Assert.AreEqual('3', EDocumentPage.EdocoumentServiceStatus.Logs.Value(), this.IncorrectValueErr); + + Clear(EDocLogList); + EDocLogList.Add(Enum::"E-Document Service Status"::"Exported"); + EDocLogList.Add(Enum::"E-Document Service Status"::"Pending Response"); + EDocLogList.Add(Enum::"E-Document Service Status"::"Pending Response"); + this.LibraryEDocument.AssertEDocumentLogs(EDocument, this.EDocumentService, EDocLogList); + + // [THEN] E-Document Errors and Warnings has correct status + this.Assert.AreEqual('', EDocumentPage.ErrorMessagesPart."Message Type".Value(), this.IncorrectValueErr); + this.Assert.AreEqual('', EDocumentPage.ErrorMessagesPart.Description.Value(), this.IncorrectValueErr); + EDocumentPage.Close(); + + // [WHEN] Executing Get Response succesfully + this.LibraryLowerPermissions.AddPermissionSet('SignUpEDCOEdit'); + this.IntegrationHelpers.SetAPIWith200Code(); + this.LibraryLowerPermissions.AddPermissionSet('SignUpEDCORead'); + JobQueueEntry.FindJobQueueEntry(JobQueueEntry."Object Type to Run"::Codeunit, Codeunit::"E-Document Get Response"); + this.LibraryJobQueue.RunJobQueueDispatcher(JobQueueEntry); + + // [When] EDocument is fetched after running ExFlow GetResponse + EDocument.FindLast(); + + // [Then] E-Document is pending response as ExFlow is async + this.Assert.AreEqual(Enum::"E-Document Status"::"In Progress", EDocument.Status, 'E-Document should be set to processed'); + + // [THEN] Open E-Document page + EDocumentPage.OpenView(); + EDocumentPage.GoToRecord(EDocument); + this.Assert.AreEqual(Format(EDocument.Direction::Outgoing), EDocumentPage.Direction.Value(), this.IncorrectValueErr); + this.Assert.AreEqual(EDocument."Document No.", EDocumentPage."Document No.".Value(), this.IncorrectValueErr); + + // [THEN] E-Document Service Status has pending response + this.Assert.AreEqual(this.EDocumentService.Code, EDocumentPage.EdocoumentServiceStatus."E-Document Service Code".Value(), this.IncorrectValueErr); + this.Assert.AreEqual(Format(Enum::"E-Document Service Status"::"Pending Response"), EDocumentPage.EdocoumentServiceStatus.Status.Value(), this.IncorrectValueErr); + this.Assert.AreEqual('4', EDocumentPage.EdocoumentServiceStatus.Logs.Value(), this.IncorrectValueErr); + + Clear(EDocLogList); + EDocLogList.Add(Enum::"E-Document Service Status"::"Exported"); + EDocLogList.Add(Enum::"E-Document Service Status"::"Pending Response"); + EDocLogList.Add(Enum::"E-Document Service Status"::"Pending Response"); + EDocLogList.Add(Enum::"E-Document Service Status"::"Pending Response"); + this.LibraryEDocument.AssertEDocumentLogs(EDocument, this.EDocumentService, EDocLogList); + + // [THEN] E-Document Errors and Warnings has correct status + this.Assert.AreEqual('', EDocumentPage.ErrorMessagesPart."Message Type".Value(), this.IncorrectValueErr); + this.Assert.AreEqual('', EDocumentPage.ErrorMessagesPart.Description.Value(), this.IncorrectValueErr); + EDocumentPage.Close(); + end; + + /// + /// Test needs MockService running to work. + /// + [Test] + [HandlerFunctions('EDocServicesPageHandler')] + procedure SubmitDocument_Error_Sent() + var + EDocument: Record "E-Document"; + JobQueueEntry: Record "Job Queue Entry"; + EDocumentPage: TestPage "E-Document"; + EDocLogList: List of [Enum "E-Document Service Status"]; + begin + // Steps: + // Pending response -> Error -> Pending response -> Sent + this.Initialize(); + this.IntegrationHelpers.SetAPIWith200Code(); + + // [Given] Team member + this.LibraryLowerPermissions.SetTeamMember(); + this.LibraryLowerPermissions.AddPermissionSet('SignUpEDCORead'); + + // [When] Posting invoice and EDocument is created + this.LibraryEDocument.PostInvoice(this.Customer); + EDocument.FindLast(); + this.LibraryEDocument.RunEDocumentJobQueue(EDocument); + + // [When] EDocument is fetched after running ExFlow SubmitDocument + EDocument.FindLast(); + + // [Then] Document Id has been correctly set on E-Document, parsed from Integration response + this.Assert.AreEqual(this.IntegrationHelpers.MockServiceDocumentId(), EDocument."Signup Document Id", 'ExFlow integration failed to set Document Id on E-Document'); + + // [Then] E-Document is pending response as ExFlow is async + this.Assert.AreEqual(Enum::"E-Document Status"::"In Progress", EDocument.Status, 'E-Document should be set to in progress'); + + // [THEN] Open E-Document page + EDocumentPage.OpenView(); + EDocumentPage.GoToRecord(EDocument); + this.Assert.AreEqual(Format(EDocument.Direction::Outgoing), EDocumentPage.Direction.Value(), this.IncorrectValueErr); + this.Assert.AreEqual(EDocument."Document No.", EDocumentPage."Document No.".Value(), this.IncorrectValueErr); + + // [THEN] E-Document Service Status has pending response + this.Assert.AreEqual(this.EDocumentService.Code, EDocumentPage.EdocoumentServiceStatus."E-Document Service Code".Value(), this.IncorrectValueErr); + this.Assert.AreEqual(Format(Enum::"E-Document Service Status"::"Pending Response"), EDocumentPage.EdocoumentServiceStatus.Status.Value(), this.IncorrectValueErr); + this.Assert.AreEqual('2', EDocumentPage.EdocoumentServiceStatus.Logs.Value(), this.IncorrectValueErr); + + Clear(EDocLogList); + EDocLogList.Add(Enum::"E-Document Service Status"::"Exported"); + EDocLogList.Add(Enum::"E-Document Service Status"::"Pending Response"); + this.LibraryEDocument.AssertEDocumentLogs(EDocument, this.EDocumentService, EDocLogList); + + // [THEN] E-Document Errors and Warnings has correct status + this.Assert.AreEqual('', EDocumentPage.ErrorMessagesPart."Message Type".Value(), this.IncorrectValueErr); + this.Assert.AreEqual('', EDocumentPage.ErrorMessagesPart.Description.Value(), this.IncorrectValueErr); + EDocumentPage.Close(); + + // [WHEN] Executing Get Response succesfully + this.LibraryLowerPermissions.AddPermissionSet('SignUpEDCOEdit'); + this.IntegrationHelpers.SetAPICode('/signup/200/response-error'); + this.LibraryLowerPermissions.AddPermissionSet('SignUpEDCORead'); + JobQueueEntry.FindJobQueueEntry(JobQueueEntry."Object Type to Run"::Codeunit, Codeunit::"E-Document Get Response"); + this.LibraryJobQueue.RunJobQueueDispatcher(JobQueueEntry); + + // [When] EDocument is fetched after running ExFlow GetResponse + EDocument.FindLast(); + + // [Then] E-Document is in error state + this.Assert.AreEqual(Enum::"E-Document Status"::Error, EDocument.Status, 'E-Document should be set to error'); + + // [THEN] Open E-Document page + EDocumentPage.OpenView(); + EDocumentPage.GoToRecord(EDocument); + this.Assert.AreEqual(Format(EDocument.Direction::Outgoing), EDocumentPage.Direction.Value(), this.IncorrectValueErr); + this.Assert.AreEqual(EDocument."Document No.", EDocumentPage."Document No.".Value(), this.IncorrectValueErr); + + // [THEN] E-Document Service Status has sending error + this.Assert.AreEqual(this.EDocumentService.Code, EDocumentPage.EdocoumentServiceStatus."E-Document Service Code".Value(), this.IncorrectValueErr); + this.Assert.AreEqual(Format(Enum::"E-Document Service Status"::"Sending Error"), EDocumentPage.EdocoumentServiceStatus.Status.Value(), this.IncorrectValueErr); + this.Assert.AreEqual('3', EDocumentPage.EdocoumentServiceStatus.Logs.Value(), this.IncorrectValueErr); + + Clear(EDocLogList); + EDocLogList.Add(Enum::"E-Document Service Status"::"Exported"); + EDocLogList.Add(Enum::"E-Document Service Status"::"Pending Response"); + EDocLogList.Add(Enum::"E-Document Service Status"::"Sending Error"); + this.LibraryEDocument.AssertEDocumentLogs(EDocument, this.EDocumentService, EDocLogList); + + EDocumentPage.ErrorMessagesPart.First(); + // [THEN] E-Document Errors and Warnings has correct status + this.Assert.AreEqual('Error', EDocumentPage.ErrorMessagesPart."Message Type".Value(), this.IncorrectValueErr); + this.Assert.AreEqual('Reason: Http error 404 document identifier not found', EDocumentPage.ErrorMessagesPart.Description.Value(), this.IncorrectValueErr); + + EDocumentPage.Close(); + + // Then user manually send + this.IntegrationHelpers.SetAPIWith200Code(); + EDocument.FindLast(); + + // [THEN] Open E-Document page and resend + EDocumentPage.OpenView(); + EDocumentPage.GoToRecord(EDocument); + EDocumentPage.Send_Promoted.Invoke(); + EDocumentPage.Close(); + + EDocument.FindLast(); + EDocumentPage.OpenView(); + EDocumentPage.GoToRecord(EDocument); + + // [Then] E-Document is pending response as ExFlow is async + this.Assert.AreEqual(Enum::"E-Document Status"::"In Progress", EDocument.Status, 'E-Document should be set to in progress'); + + this.Assert.AreEqual(Format(EDocument.Direction::Outgoing), EDocumentPage.Direction.Value(), this.IncorrectValueErr); + this.Assert.AreEqual(EDocument."Document No.", EDocumentPage."Document No.".Value(), this.IncorrectValueErr); + + // [THEN] E-Document Service Status has pending response + this.Assert.AreEqual(this.EDocumentService.Code, EDocumentPage.EdocoumentServiceStatus."E-Document Service Code".Value(), this.IncorrectValueErr); + this.Assert.AreEqual(Format(Enum::"E-Document Service Status"::"Pending Response"), EDocumentPage.EdocoumentServiceStatus.Status.Value(), this.IncorrectValueErr); + this.Assert.AreEqual('4', EDocumentPage.EdocoumentServiceStatus.Logs.Value(), this.IncorrectValueErr); + + Clear(EDocLogList); + EDocLogList.Add(Enum::"E-Document Service Status"::"Exported"); + EDocLogList.Add(Enum::"E-Document Service Status"::"Pending Response"); + EDocLogList.Add(Enum::"E-Document Service Status"::"Sending Error"); + EDocLogList.Add(Enum::"E-Document Service Status"::"Pending Response"); + this.LibraryEDocument.AssertEDocumentLogs(EDocument, this.EDocumentService, EDocLogList); + + // [THEN] E-Document Errors and Warnings has correct status + this.Assert.AreEqual('', EDocumentPage.ErrorMessagesPart."Message Type".Value(), this.IncorrectValueErr); + this.Assert.AreEqual('', EDocumentPage.ErrorMessagesPart.Description.Value(), this.IncorrectValueErr); + EDocumentPage.Close(); + + this.LibraryLowerPermissions.AddPermissionSet('SignUpEDCOEdit'); + this.IntegrationHelpers.SetAPIWith200Code(); + this.LibraryLowerPermissions.AddPermissionSet('SignUpEDCORead'); + + JobQueueEntry.FindJobQueueEntry(JobQueueEntry."Object Type to Run"::Codeunit, Codeunit::"E-Document Get Response"); + this.LibraryJobQueue.RunJobQueueDispatcher(JobQueueEntry); + + // [When] EDocument is fetched after running ExFlow GetResponse + EDocument.FindLast(); + + // [Then] E-Document is pending response as ExFlow is async + this.Assert.AreEqual(Enum::"E-Document Status"::"In Progress", EDocument.Status, 'E-Document should be set to processed'); + + // [THEN] Open E-Document page + EDocumentPage.OpenView(); + EDocumentPage.GoToRecord(EDocument); + this.Assert.AreEqual(Format(EDocument.Direction::Outgoing), EDocumentPage.Direction.Value(), this.IncorrectValueErr); + this.Assert.AreEqual(EDocument."Document No.", EDocumentPage."Document No.".Value(), this.IncorrectValueErr); + + // [THEN] E-Document Service Status has pending response + this.Assert.AreEqual(this.EDocumentService.Code, EDocumentPage.EdocoumentServiceStatus."E-Document Service Code".Value(), this.IncorrectValueErr); + this.Assert.AreEqual(Format(Enum::"E-Document Service Status"::"Pending Response"), EDocumentPage.EdocoumentServiceStatus.Status.Value(), this.IncorrectValueErr); + this.Assert.AreEqual('5', EDocumentPage.EdocoumentServiceStatus.Logs.Value(), this.IncorrectValueErr); + + Clear(EDocLogList); + EDocLogList.Add(Enum::"E-Document Service Status"::"Exported"); + EDocLogList.Add(Enum::"E-Document Service Status"::"Pending Response"); + EDocLogList.Add(Enum::"E-Document Service Status"::"Sending Error"); + EDocLogList.Add(Enum::"E-Document Service Status"::"Pending Response"); + EDocLogList.Add(Enum::"E-Document Service Status"::"Pending Response"); + this.LibraryEDocument.AssertEDocumentLogs(EDocument, this.EDocumentService, EDocLogList); + + // [THEN] E-Document Errors and Warnings has correct status + this.Assert.AreEqual('', EDocumentPage.ErrorMessagesPart."Message Type".Value(), this.IncorrectValueErr); + this.Assert.AreEqual('', EDocumentPage.ErrorMessagesPart.Description.Value(), this.IncorrectValueErr); + EDocumentPage.Close(); + end; + + /// + /// Test needs MockService running to work. + /// + [Test] + procedure SubmitDocumentServiceDown() + var + EDocument: Record "E-Document"; + EDocumentPage: TestPage "E-Document"; + EDocLogList: List of [Enum "E-Document Service Status"]; + begin + this.Initialize(); + this.IntegrationHelpers.SetAPIWith500Code(); + + // [Given] Team member + this.LibraryLowerPermissions.SetTeamMember(); + this.LibraryLowerPermissions.AddPermissionSet('SignUpEDCORead'); + + // [When] Posting invoice and EDocument is created + this.LibraryEDocument.PostInvoice(this.Customer); + EDocument.FindLast(); + this.LibraryEDocument.RunEDocumentJobQueue(EDocument); + + // [When] EDocument is fetched after running Avalara SubmitDocument + EDocument.FindLast(); + + this.Assert.AreEqual(Enum::"E-Document Status"::Error, EDocument.Status, 'E-Document should be set to error state when service is down.'); + this.Assert.AreEqual('', EDocument."Signup Document Id", 'Document Id on E-Document should not be set.'); + + EDocumentPage.OpenView(); + EDocumentPage.GoToRecord(EDocument); + + // [THEN] E-Document has correct error status + this.Assert.AreEqual(Format(EDocument.Status::Error), EDocumentPage."Electronic Document Status".Value(), this.IncorrectValueErr); + this.Assert.AreEqual(Format(EDocument.Direction::Outgoing), EDocumentPage.Direction.Value(), this.IncorrectValueErr); + this.Assert.AreEqual(EDocument."Document No.", EDocumentPage."Document No.".Value(), this.IncorrectValueErr); + + // [THEN] E-Document Service Status has correct error status + this.Assert.AreEqual(this.EDocumentService.Code, EDocumentPage.EdocoumentServiceStatus."E-Document Service Code".Value(), this.IncorrectValueErr); + this.Assert.AreEqual(Format(Enum::"E-Document Service Status"::"Sending Error"), EDocumentPage.EdocoumentServiceStatus.Status.Value(), this.IncorrectValueErr); + this.Assert.AreEqual('2', EDocumentPage.EdocoumentServiceStatus.Logs.Value(), this.IncorrectValueErr); + + Clear(EDocLogList); + EDocLogList.Add(Enum::"E-Document Service Status"::"Exported"); + EDocLogList.Add(Enum::"E-Document Service Status"::"Sending Error"); + this.LibraryEDocument.AssertEDocumentLogs(EDocument, this.EDocumentService, EDocLogList); + + // [THEN] E-Document Errors and Warnings has correct status + this.Assert.AreEqual('Error', EDocumentPage.ErrorMessagesPart."Message Type".Value(), this.IncorrectValueErr); + this.Assert.AreEqual('There was an error sending the request. Response code: 500 and error message: Internal Server Error', EDocumentPage.ErrorMessagesPart.Description.Value(), this.IncorrectValueErr); + end; + + /// + /// Test needs MockService running to work. + /// + [Test] + procedure SubmitGetDocuments() + var + EDocument: Record "E-Document"; + //PurchaseHeader: Record "Purchase Header"; + IntegrationEvents: Codeunit IntegrationEvents; + EDocumentServicesPage: TestPage "E-Document Service"; + TmpDocCount: Integer; + begin + this.Initialize(); + + // Open and close E-Doc page creates auto import job due to setting + EDocumentServicesPage.OpenView(); + EDocumentServicesPage.GoToRecord(this.EDocumentService); + EDocumentServicesPage."Resolve Unit Of Measure".SetValue(false); + EDocumentServicesPage."Lookup Item Reference".SetValue(true); + EDocumentServicesPage."Lookup Item GTIN".SetValue(false); + EDocumentServicesPage."Lookup Account Mapping".SetValue(false); + EDocumentServicesPage."Validate Line Discount".SetValue(false); + EDocumentServicesPage."Auto Import".SetValue(true); + EDocumentServicesPage.Close(); + + TmpDocCount := EDocument.Count(); + BindSubscription(IntegrationEvents); + // Manually fire job queue job to import + this.LibraryEDocument.RunImportJob(); + UnbindSubscription(IntegrationEvents); + + // Assert that we have Purchase Invoice created + this.Assert.AreEqual(EDocument.Count(), TmpDocCount + 1, 'The document was not imported!'); + end; + + /// + /// Test needs MockService running to work. + /// + [Test] + procedure GetMetadataProfiles() + var + MetadataProfile: Record MetadataProfile; + EDocServiceSupportedTypes: TestPage "E-Doc Service Supported Types"; + begin + this.Initialize(); + + MetadataProfile.Reset(); + MetadataProfile.DeleteAll(); + + // Populate metadata profiles + EDocServiceSupportedTypes.OpenView(); + EDocServiceSupportedTypes.PopulateMetaData.Invoke(); + EDocServiceSupportedTypes.Close(); + + this.Assert.TableIsNotEmpty(Database::MetadataProfile); + end; + + local procedure Initialize() + var + ConnectionSetup: Record ConnectionSetup; + CompanyInformation: Record "Company Information"; + ServiceParticipant: Record "Service Participant"; + Authentication: Codeunit Authentication; + begin + this.LibraryLowerPermissions.SetOutsideO365Scope(); + + ConnectionSetup.DeleteAll(); + Authentication.InitConnectionSetup(); + this.IntegrationHelpers.SetCommonConnectionSetup(); + this.IntegrationHelpers.SetAPIWith200Code(); + + if this.IsInitialized then + exit; + + this.CreateDefaultMetadataProfile(); + this.LibraryEDocument.SetupStandardVAT(); + this.LibraryEDocument.SetupStandardSalesScenario(this.Customer, this.EDocumentService, Enum::"E-Document Format"::"PEPPOL BIS 3.0", Enum::"Service Integration"::"ExFlow E-Invoicing PTE"); + this.LibraryEDocument.SetupStandardPurchaseScenario(this.Vendor, this.EDocumentService, Enum::"E-Document Format"::"PEPPOL BIS 3.0", Enum::"Service Integration"::"ExFlow E-Invoicing PTE"); + this.EDocumentService."Auto Import" := true; + this.EDocumentService."Import Minutes between runs" := 5; + this.EDocumentService."Import Start Time" := Time(); + this.EDocumentService.Modify(); + + this.LibraryInventory.CreateItem(this.Item); + + this.Vendor.Name := 'CRONUS GB SELLER'; + this.Vendor."VAT Registration No." := '777777777'; // GB777777771 + this.Vendor."Receive E-Document To" := Enum::"E-Document Type"::"Purchase Invoice"; + this.Vendor.Modify(); + + // Vendor to get invoices from + Clear(ServiceParticipant); + ServiceParticipant.Service := this.EDocumentService.Code; + ServiceParticipant."Participant Type" := ServiceParticipant."Participant Type"::Vendor; + ServiceParticipant.Participant := this.Vendor."No."; + ServiceParticipant."Participant Identifier" := this.IntegrationHelpers.MockCompanyId(); + ServiceParticipant.Insert(); + + // Customer to send invoice to + Clear(ServiceParticipant); + ServiceParticipant.Service := this.EDocumentService.Code; + ServiceParticipant."Participant Type" := ServiceParticipant."Participant Type"::Customer; + ServiceParticipant.Participant := this.Customer."No."; + ServiceParticipant."Participant Identifier" := this.IntegrationHelpers.MockCompanyId(); + ServiceParticipant.Insert(); + + CompanyInformation.Get(); + CompanyInformation."VAT Registration No." := '777777777'; // GB777777771 + CompanyInformation."SignUp Service Participant Id" := this.IntegrationHelpers.MockCompanyId(); + CompanyInformation.Modify(); + + this.ApplyMetadataProfile(this.GetMetadataProfileId()); + + this.IsInitialized := true; + end; + + local procedure CreateDefaultMetadataProfile() + var + MetadataProfile: Record MetadataProfile; + begin + if not MetadataProfile.IsEmpty() then + MetadataProfile.DeleteAll(true); + + MetadataProfile.Init(); + MetadataProfile.Validate("Profile ID", this.GetMetadataProfileId()); + MetadataProfile.Validate("Profile Name", 'PEPPOL BIS Billing v 3 Invoice UBL'); + MetadataProfile.Validate("Process Identifier Scheme", 'cenbii-procid-ubl'); + MetadataProfile.Validate("Process Identifier Value", 'urn:fdc:peppol.eu:2017:poacc:billing:01:1.0'); + MetadataProfile.Validate("Document Identifier Scheme", 'busdox-docid-qns'); + MetadataProfile.Validate("Document Identifier Value", 'urn:oasis:names:specification:ubl:schema:xsd:Invoice-2::Invoice##urn:cen.eu:en16931:2017#compliant#urn:fdc:peppol.eu:2017:poacc:billing:3.0::2.1'); + MetadataProfile.Insert(true); + end; + + local procedure ApplyMetadataProfile(ProfileID: Integer) + var + EDocServiceSupportedType: Record "E-Doc. Service Supported Type"; + begin + if EDocServiceSupportedType.FindSet(true) then + repeat + EDocServiceSupportedType.Validate("Profile Id", ProfileID); + EDocServiceSupportedType.Modify(true); + until EDocServiceSupportedType.Next() = 0; + end; + + local procedure GetMetadataProfileId(): Integer + begin + exit(158); + end; + + [ModalPageHandler] + internal procedure EDocServicesPageHandler(var EDocumentServicesPage: TestPage "E-Document Services") + begin + EDocumentServicesPage.Filter.SetFilter(Code, this.EDocumentService.Code); + EDocumentServicesPage.OK().Invoke(); + end; + + [StrMenuHandler] + internal procedure ExternalHttpRequestHandler(Options: Text[1024]; var Choice: Integer; Instruction: Text[1024]) + var + ExternalHttpRequestChoice: Option " ","Allow Always","Allow Once","Block Always","Block Once"; + begin + Choice := ExternalHttpRequestChoice::"Allow Always"; + end; +} \ No newline at end of file