mirror of
https://github.com/microsoft/BCQuality.git
synced 2026-08-08 18:31:36 +01:00
Add new action skills for AL testing and documentation
- Introduced `al-test-writer` to generate AL test codeunits for production objects based on TDD principles. - Added `al-userguide-test-writer` to create test codeunits from user guide steps, mapping actions and assertions. - Implemented `bc-extension-test-guide` to generate a comprehensive TEST_GUIDE.md for Business Central extensions, covering various categories. - Created `bc-webclient-runner` to automate UI testing of the Business Central web client, capturing screenshots and asserting UI states. - Developed `page-scripting-e2e` to produce a recording plan for Page Scripting, ensuring a structured approach to browser-level testing.
This commit is contained in:
parent
822cae1b27
commit
07140e2223
76 changed files with 4353 additions and 6 deletions
|
|
@ -0,0 +1,47 @@
|
|||
// Best practice: every outbound call carries Idempotency-Key = the Integration Message GUID.
|
||||
// The key is created once when the message is staged and never changes, so the first call
|
||||
// and every retry (Job Queue or operator-driven) send the SAME key. A well-behaved receiver
|
||||
// collapses them into a single side effect and returns the original response.
|
||||
|
||||
codeunit 50150 "Outbound Caller"
|
||||
{
|
||||
procedure Send(var IntegrationMessage: Record "Integration Message")
|
||||
var
|
||||
Client: HttpClient;
|
||||
Request: HttpRequestMessage;
|
||||
Content: HttpContent;
|
||||
ContentHeaders: HttpHeaders;
|
||||
RequestHeaders: HttpHeaders;
|
||||
Response: HttpResponseMessage;
|
||||
begin
|
||||
Content.WriteFrom(IntegrationMessage.GetRequest());
|
||||
|
||||
// Content-Type belongs on the content headers, not the request headers.
|
||||
Content.GetHeaders(ContentHeaders);
|
||||
if ContentHeaders.Contains('Content-Type') then
|
||||
ContentHeaders.Remove('Content-Type');
|
||||
ContentHeaders.Add('Content-Type', 'application/json');
|
||||
|
||||
Request.Content := Content;
|
||||
Request.Method := 'POST';
|
||||
Request.SetRequestUri('https://pay.contoso.com/api/charges');
|
||||
Request.GetHeaders(RequestHeaders);
|
||||
|
||||
// THE key line. The value is the staged Message ID, which is stable for the life of
|
||||
// the message. Calling Send again for the same row sends this exact same value, so the
|
||||
// payment service sees the retry as a repeat of one charge and captures money once.
|
||||
RequestHeaders.Add('Idempotency-Key', StableKey(IntegrationMessage));
|
||||
|
||||
// After an UNCERTAIN failure (timeout, dropped connection, 502) the Job Queue will
|
||||
// re-run this message. Because the key is unchanged, the retry is safe: no double charge.
|
||||
Client.Send(Request, Response);
|
||||
IntegrationMessage.RecordResult(Response);
|
||||
end;
|
||||
|
||||
// The key is derived purely from the durable message id. Nothing here changes between
|
||||
// attempts: no CreateGuid, no timestamp, no attempt counter.
|
||||
local procedure StableKey(IntegrationMessage: Record "Integration Message"): Text
|
||||
begin
|
||||
exit(DelChr(LowerCase(Format(IntegrationMessage."Message ID")), '=', '{}'));
|
||||
end;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue