unit PSQLNotifyTest;
{$IFDEF DUNITX}
  {$M+}
{$ENDIF}
{

  Delphi DUnit Test Case
  ----------------------
  This unit contains a skeleton test case class generated by the Test Case Wizard.
  Modify the generated code to correctly setup and call the methods from the unit
  being tested.

}

interface

uses
  Classes, PSQLNotify, PSQLTypes, PSQLAccess, PSQLDbTables,
  {$IFNDEF DUNITX}
  TestFramework, TestExtensions, TestHelper
  {$ELSE}
  DUnitX.TestFramework, TestXHelper
  {$ENDIF};

type
  THandlerClass = class
    class procedure NotifyHandler(Sender: TObject; Event: string; ProcessID : Integer);
    class procedure NotifyHandlerEx(Sender: TObject; Channel: string; Payload: string; ProcessID : Integer);
  end;

  {$IFDEF DUNITX}[TestFixture]{$ENDIF}
  TestTPSQLNotify = class({$IFNDEF DUNITX}TTestCase{$ELSE}TTestXCase{$ENDIF})
  private
    FPSQLNotify: TPSQLNotify;
    {$IFDEF DUNITX}
    procedure InternalSetUp;
    procedure InternalTearDown;
    {$ENDIF}
  public
    {$IFNDEF DUNITX}
    procedure SetUp; override;
    procedure TearDown; override;
    {$ELSE}
    [Setup]
    procedure SetUp;
    [TearDown]
    procedure TearDown;
    {$ENDIF}
  published
    procedure TestOpenNotify;
    procedure TestCloseNotify;
    procedure TestListenTo;
    procedure TestSendNotify;
    procedure TestSendNotify1;
    procedure TestUnlistenTo;
    procedure TestUnlistenAll;
    {$IFDEF DUNITX}
    [SetupFixture]
    procedure SetupFixture;
    [TearDownFixture]
    procedure TearDownFixture;
    {$ENDIF}
  end;

var
  TestNotify: TPSQLNotify;
  MsgReceived, MsgReceivedEx: boolean;

implementation

{$IFDEF DUNITX}
procedure TestTPSQLNotify.InternalSetUp;
begin
  TestNotify := TPSQLNotify.Create(nil);
  TestNotify.Database := TestDBSetup.Database;
  TestNotify.ListenList.CommaText := 'first,second,third,custom';
  TestNotify.OnNotify := THandlerClass.NotifyHandler;
  TestNotify.OnNotifyEx := THandlerClass.NotifyHandlerEx;
  TestNotify.Active := True;
  Check(TestDBSetup.Database.ServerVersionAsInt > 090000, 'Server version less then 9.0 to test Payload functionality');
end;

procedure TestTPSQLNotify.InternalTearDown;
begin
{$IFNDEF NEXTGEN}
  TestNotify.Free;
{$ELSE}
  TestNotify.DisposeOf;
{$ENDIF}
  if not MsgReceived then Status('Simple notify message lost');
  if not MsgReceivedEx then Status('Payload notify message lost');
end;
{$ENDIF}

procedure TestTPSQLNotify.SetUp;
begin
  FPSQLNotify := TPSQLNotify.Create(nil);
  FPSQLNotify.Database := TestDBSetup.Database;
  FPSQLNotify.ListenList.CommaText := 'first,second,third';
end;

{$IFDEF DUNITX}
procedure TestTPSQLNotify.SetupFixture;
begin
  InternalSetUp;
end;
procedure TestTPSQLNotify.TearDownFixture;
begin
  InternalTearDown;
end;
{$ENDIF}

procedure TestTPSQLNotify.TearDown;
begin
{$IFNDEF NEXTGEN}
  FPSQLNotify.Free;
{$ELSE}
  FPSQLNotify.DisposeOf;
{$ENDIF}
  FPSQLNotify := nil;
end;

procedure TestTPSQLNotify.TestOpenNotify;
begin
  FPSQLNotify.OpenNotify;
  Check(FPSQLNotify.Active, 'Notify is not active');
end;

procedure TestTPSQLNotify.TestCloseNotify;
begin
  FPSQLNotify.CloseNotify;
  Check(not FPSQLNotify.Active, 'Notify is active');
end;

procedure TestTPSQLNotify.TestListenTo;
var
  Event: string;
begin
  Event := 'custom';
  FPSQLNotify.OpenNotify();
  FPSQLNotify.ListenTo(Event);
  Check(FPSQLNotify.ListenList.IndexOf(Event) > -1, 'ListenTo failed');
end;

procedure TestTPSQLNotify.TestSendNotify;
var
  Event: string;
begin
  Event := 'first';
  FPSQLNotify.OpenNotify();
  FPSQLNotify.SendNotify(Event);
end;

procedure TestTPSQLNotify.TestSendNotify1;
var
  Payload: string;
  Channel: string;
begin
  Channel := 'second';
  Payload := 'the second channel';
  FPSQLNotify.OpenNotify();
  FPSQLNotify.SendNotify(Channel, Payload);
end;

procedure TestTPSQLNotify.TestUnlistenTo;
var
  Event: string;
begin
  Event := 'third';
  FPSQLNotify.OpenNotify();
  FPSQLNotify.UnlistenTo(Event);
  Check(FPSQLNotify.ListenList.IndexOf(Event) = -1, 'UnlistenTo doesn''t exclude event');
end;

procedure TestTPSQLNotify.TestUnlistenAll;
begin
  FPSQLNotify.OpenNotify();
  FPSQLNotify.UnlistenAll;
  Check(FPSQLNotify.ListenList.Count = 0, 'UnlistenAll doesn''t clear events');
end;

class procedure THandlerClass.NotifyHandler(Sender: TObject; Event: string;
  ProcessID: Integer);
begin
  if TestDBSetup.Database.GetBackendPID = ProcessID then //it's ours
    if not MsgReceived then
      MsgReceived := (Event = 'first');
end;

class procedure THandlerClass.NotifyHandlerEx(Sender: TObject; Channel,
  Payload: string; ProcessID: Integer);
begin
  if TestDBSetup.Database.GetBackendPID = ProcessID then //it's ours
   begin
    if not MsgReceived then
      MsgReceived := (Channel = 'first');
    if not MsgReceivedEx then
      MsgReceivedEx := (Channel = 'second') and (Payload = 'the second channel');
   end;
end;

initialization
 {$IFDEF DUNITX}
  TDUnitX.RegisterTestFixture(TestTPSQLNotify);
{$ENDIF}

end.

