228 lines
15 KiB
Transact-SQL
228 lines
15 KiB
Transact-SQL
-- Run against a migrated verification/dev database with at least one project and scene.
|
|
-- All fixture changes are rolled back, including on assertion failure.
|
|
SET XACT_ABORT ON;
|
|
BEGIN TRY
|
|
BEGIN TRANSACTION;
|
|
DECLARE @ProjectID int, @UserID int, @SceneID int;
|
|
SELECT TOP (1) @ProjectID = p.ProjectID, @UserID = p.UserID, @SceneID = s.SceneID
|
|
FROM dbo.ProjectUserAccess p JOIN dbo.Books b ON b.ProjectID = p.ProjectID
|
|
JOIN dbo.Chapters c ON c.BookID = b.BookID JOIN dbo.Scenes s ON s.ChapterID = c.ChapterID
|
|
WHERE p.IsActive = 1;
|
|
IF @SceneID IS NULL THROW 51001, 'Merge tests require a project with a scene and active user.', 1;
|
|
DECLARE @Source int, @Target int, @Child int;
|
|
INSERT dbo.Locations(ProjectID, LocationName) VALUES (@ProjectID, N'Merge test old observatory'); SET @Source = SCOPE_IDENTITY();
|
|
INSERT dbo.Locations(ProjectID, LocationName, Description) VALUES (@ProjectID, N'Merge test observatory', N'Keep target details'); SET @Target = SCOPE_IDENTITY();
|
|
INSERT dbo.Locations(ProjectID, LocationName, ParentLocationID) VALUES (@ProjectID, N'Merge test dome', @Source); SET @Child = SCOPE_IDENTITY();
|
|
INSERT dbo.LocationAliases(LocationID, Alias) VALUES (@Source, N'North tower'), (@Target, N'North tower'), (@Source, N'Old dome');
|
|
INSERT dbo.WordCompanionSceneLocations(SceneID, LocationID) VALUES (@SceneID, @Source), (@SceneID, @Target);
|
|
INSERT dbo.SceneLocationSuggestions(SceneID, LocationID, CreatedByUserID) VALUES (@SceneID, @Source, @UserID), (@SceneID, @Target, @UserID);
|
|
UPDATE dbo.Scenes SET PrimaryLocationID = @Source WHERE SceneID = @SceneID;
|
|
DECLARE @RelType int = (SELECT TOP (1) LocationRelationshipTypeID FROM dbo.LocationRelationshipTypes);
|
|
INSERT dbo.LocationRelationships(FromLocationID, ToLocationID, LocationRelationshipTypeID)
|
|
VALUES (@Source,@Target,@RelType),(@Source,@Child,@RelType),(@Target,@Child,@RelType);
|
|
EXEC dbo.Location_Merge @Source, @Target, @UserID;
|
|
IF NOT EXISTS (SELECT 1 FROM dbo.Locations WHERE LocationID=@Source AND IsArchived=1) THROW 51001, 'Source location was not archived.', 1;
|
|
IF NOT EXISTS (SELECT 1 FROM dbo.Locations WHERE LocationID=@Child AND ParentLocationID=@Target) THROW 51001, 'Child location was not moved.', 1;
|
|
IF NOT EXISTS (SELECT 1 FROM dbo.Scenes WHERE SceneID=@SceneID AND PrimaryLocationID=@Target) THROW 51001, 'Primary scene location was not moved.', 1;
|
|
IF (SELECT COUNT(*) FROM dbo.LocationAliases WHERE LocationID=@Target) <> 3 THROW 51001, 'Location names were lost or duplicated.', 1;
|
|
IF (SELECT COUNT(*) FROM dbo.WordCompanionSceneLocations WHERE SceneID=@SceneID AND LocationID=@Target) <> 1 THROW 51001, 'Duplicate location scene link.', 1;
|
|
IF (SELECT COUNT(*) FROM dbo.SceneLocationSuggestions WHERE SceneID=@SceneID AND LocationID=@Target AND Status=N'Pending') <> 1 THROW 51001, 'Duplicate location suggestion.', 1;
|
|
IF (SELECT COUNT(*) FROM dbo.LocationRelationships WHERE FromLocationID=@Target AND ToLocationID=@Child AND IsArchived=0) <> 1 THROW 51001, 'Duplicate location relationship.', 1;
|
|
IF EXISTS (SELECT 1 FROM dbo.LocationRelationships WHERE (FromLocationID=@Source OR ToLocationID=@Source) AND IsArchived=0) THROW 51001, 'Active relationship left on source.', 1;
|
|
IF NOT EXISTS (SELECT 1 FROM dbo.Locations WHERE LocationID=@Target AND Description=N'Keep target details') THROW 51001, 'Target location details changed.', 1;
|
|
|
|
DECLARE @Kind int = (SELECT TOP (1) AssetKindID FROM dbo.AssetKinds), @Other int;
|
|
INSERT dbo.StoryAssets(ProjectID, AssetName, AssetKindID) VALUES (@ProjectID,N'Merge test brass compass',@Kind); SET @Source=SCOPE_IDENTITY();
|
|
INSERT dbo.StoryAssets(ProjectID, AssetName, AssetKindID,Description) VALUES (@ProjectID,N'Merge test compass',@Kind,N'Keep target details'); SET @Target=SCOPE_IDENTITY();
|
|
INSERT dbo.StoryAssets(ProjectID, AssetName, AssetKindID) VALUES (@ProjectID,N'Merge test map',@Kind); SET @Other=SCOPE_IDENTITY();
|
|
INSERT dbo.AssetAliases(StoryAssetID, Alias) VALUES (@Source,N'Navigator'),(@Target,N'Navigator'),(@Source,N'Brass guide');
|
|
INSERT dbo.WordCompanionSceneAssets(SceneID,StoryAssetID) VALUES (@SceneID,@Source),(@SceneID,@Target);
|
|
INSERT dbo.SceneAssetSuggestions(SceneID,AssetID,CreatedByUserID) VALUES (@SceneID,@Source,@UserID),(@SceneID,@Target,@UserID);
|
|
DECLARE @EventType int=(SELECT TOP (1) AssetEventTypeID FROM dbo.AssetEventTypes), @CustodyType int=(SELECT TOP (1) AssetCustodyEventTypeID FROM dbo.AssetCustodyEventTypes);
|
|
INSERT dbo.AssetEvents(StoryAssetID,SceneID,AssetEventTypeID,EventTitle) VALUES (@Source,@SceneID,@EventType,N'Merge test event');
|
|
DECLARE @EventID int=SCOPE_IDENTITY();
|
|
INSERT dbo.AssetCustodyEvents(StoryAssetID,SceneID,AssetCustodyEventTypeID) VALUES (@Source,@SceneID,@CustodyType);
|
|
DECLARE @CustodyID int=SCOPE_IDENTITY(), @DepType int=(SELECT TOP (1) AssetDependencyTypeID FROM dbo.AssetDependencyTypes);
|
|
INSERT dbo.AssetDependencies(SourceAssetID,TargetAssetID,AssetDependencyTypeID) VALUES (@Source,@Target,@DepType),(@Source,@Other,@DepType),(@Target,@Other,@DepType);
|
|
EXEC dbo.StoryAsset_Merge @Source,@Target,@UserID;
|
|
IF NOT EXISTS (SELECT 1 FROM dbo.StoryAssets WHERE StoryAssetID=@Source AND IsArchived=1) THROW 51001, 'Source asset was not archived.', 1;
|
|
IF (SELECT COUNT(*) FROM dbo.AssetAliases WHERE StoryAssetID=@Target) <> 3 THROW 51001, 'Asset names were lost or duplicated.', 1;
|
|
IF (SELECT COUNT(*) FROM dbo.WordCompanionSceneAssets WHERE SceneID=@SceneID AND StoryAssetID=@Target) <> 1 THROW 51001, 'Duplicate asset scene link.', 1;
|
|
IF (SELECT COUNT(*) FROM dbo.SceneAssetSuggestions WHERE SceneID=@SceneID AND AssetID=@Target AND Status=N'Pending') <> 1 THROW 51001, 'Duplicate asset suggestion.', 1;
|
|
IF NOT EXISTS (SELECT 1 FROM dbo.AssetEvents WHERE AssetEventID=@EventID AND StoryAssetID=@Target) THROW 51001, 'Asset event was not moved.', 1;
|
|
IF NOT EXISTS (SELECT 1 FROM dbo.AssetCustodyEvents WHERE AssetCustodyEventID=@CustodyID AND StoryAssetID=@Target) THROW 51001, 'Custody was not moved.', 1;
|
|
IF (SELECT COUNT(*) FROM dbo.AssetDependencies WHERE SourceAssetID=@Target AND TargetAssetID=@Other AND IsArchived=0) <> 1 THROW 51001, 'Duplicate asset dependency.', 1;
|
|
IF EXISTS (SELECT 1 FROM dbo.AssetDependencies WHERE (SourceAssetID=@Source OR TargetAssetID=@Source) AND IsArchived=0) THROW 51001, 'Active dependency left on source.', 1;
|
|
IF NOT EXISTS (SELECT 1 FROM dbo.StoryAssets WHERE StoryAssetID=@Target AND Description=N'Keep target details') THROW 51001, 'Target asset details changed.', 1;
|
|
ROLLBACK TRANSACTION;
|
|
SELECT N'PASS: location and asset merges; fixtures rolled back' AS Result;
|
|
END TRY
|
|
BEGIN CATCH
|
|
IF XACT_STATE() <> 0 ROLLBACK TRANSACTION;
|
|
THROW;
|
|
END CATCH;
|
|
GO
|
|
-- Hierarchy failure must also leave the source unmodified (the procedure rolls back the fixtures).
|
|
BEGIN TRY
|
|
BEGIN TRANSACTION;
|
|
DECLARE @ProjectID int, @UserID int, @Source int, @Target int;
|
|
SELECT TOP (1) @ProjectID=ProjectID,@UserID=UserID FROM dbo.ProjectUserAccess WHERE IsActive=1;
|
|
INSERT dbo.Locations(ProjectID,LocationName) VALUES (@ProjectID,N'Merge cycle test parent'); SET @Source=SCOPE_IDENTITY();
|
|
INSERT dbo.Locations(ProjectID,LocationName,ParentLocationID) VALUES (@ProjectID,N'Merge cycle test child',@Source); SET @Target=SCOPE_IDENTITY();
|
|
EXEC dbo.Location_Merge @Source,@Target,@UserID;
|
|
THROW 51001, 'Hierarchy cycle was accepted.', 1;
|
|
END TRY
|
|
BEGIN CATCH
|
|
IF XACT_STATE() <> 0 ROLLBACK TRANSACTION;
|
|
IF ERROR_NUMBER() <> 51000 OR ERROR_MESSAGE() NOT LIKE '%descendants%' THROW;
|
|
SELECT N'PASS: hierarchy cycle rejected; fixtures rolled back' AS Result;
|
|
END CATCH;
|
|
|
|
GO
|
|
-- Reject same record for Location without leaving fixture data behind.
|
|
BEGIN TRY
|
|
BEGIN TRANSACTION;
|
|
DECLARE @ProjectID int, @UserID int, @Source int, @Target int;
|
|
SELECT TOP (1) @ProjectID=ProjectID,@UserID=UserID FROM dbo.ProjectUserAccess WHERE IsActive=1;
|
|
INSERT dbo.Locations(ProjectID,LocationName) VALUES (@ProjectID,N'Merge validation source'); SET @Source=SCOPE_IDENTITY();
|
|
INSERT dbo.Locations(ProjectID,LocationName) VALUES (@ProjectID,N'Merge validation target'); SET @Target=SCOPE_IDENTITY();
|
|
SET @Target=@Source;
|
|
EXEC dbo.Location_Merge @Source,@Target,@UserID;
|
|
THROW 51001, 'Invalid merge was accepted.', 1;
|
|
END TRY
|
|
BEGIN CATCH
|
|
IF XACT_STATE() <> 0 ROLLBACK TRANSACTION;
|
|
IF ERROR_NUMBER() <> 51000 THROW;
|
|
SELECT N'PASS: Location rejects same record; fixtures rolled back' AS Result;
|
|
END CATCH;
|
|
|
|
GO
|
|
-- Reject archived target for Location without leaving fixture data behind.
|
|
BEGIN TRY
|
|
BEGIN TRANSACTION;
|
|
DECLARE @ProjectID int, @UserID int, @Source int, @Target int;
|
|
SELECT TOP (1) @ProjectID=ProjectID,@UserID=UserID FROM dbo.ProjectUserAccess WHERE IsActive=1;
|
|
INSERT dbo.Locations(ProjectID,LocationName) VALUES (@ProjectID,N'Merge validation source'); SET @Source=SCOPE_IDENTITY();
|
|
INSERT dbo.Locations(ProjectID,LocationName) VALUES (@ProjectID,N'Merge validation target'); SET @Target=SCOPE_IDENTITY();
|
|
UPDATE dbo.Locations SET IsArchived=1 WHERE LocationID=@Target;
|
|
EXEC dbo.Location_Merge @Source,@Target,@UserID;
|
|
THROW 51001, 'Invalid merge was accepted.', 1;
|
|
END TRY
|
|
BEGIN CATCH
|
|
IF XACT_STATE() <> 0 ROLLBACK TRANSACTION;
|
|
IF ERROR_NUMBER() <> 51000 THROW;
|
|
SELECT N'PASS: Location rejects archived target; fixtures rolled back' AS Result;
|
|
END CATCH;
|
|
|
|
GO
|
|
-- Reject other project for Location without leaving fixture data behind.
|
|
BEGIN TRY
|
|
BEGIN TRANSACTION;
|
|
DECLARE @ProjectID int, @UserID int, @Source int, @Target int;
|
|
SELECT TOP (1) @ProjectID=ProjectID,@UserID=UserID FROM dbo.ProjectUserAccess WHERE IsActive=1;
|
|
INSERT dbo.Locations(ProjectID,LocationName) VALUES (@ProjectID,N'Merge validation source'); SET @Source=SCOPE_IDENTITY();
|
|
INSERT dbo.Locations(ProjectID,LocationName) VALUES (@ProjectID,N'Merge validation target'); SET @Target=SCOPE_IDENTITY();
|
|
INSERT dbo.Projects(ProjectName) VALUES (N'Merge test other project');
|
|
DECLARE @OtherProjectID int=SCOPE_IDENTITY();
|
|
UPDATE dbo.Locations SET ProjectID=@OtherProjectID WHERE LocationID=@Target;
|
|
EXEC dbo.Location_Merge @Source,@Target,@UserID;
|
|
THROW 51001, 'Invalid merge was accepted.', 1;
|
|
END TRY
|
|
BEGIN CATCH
|
|
IF XACT_STATE() <> 0 ROLLBACK TRANSACTION;
|
|
IF ERROR_NUMBER() <> 51000 THROW;
|
|
SELECT N'PASS: Location rejects other project; fixtures rolled back' AS Result;
|
|
END CATCH;
|
|
|
|
GO
|
|
-- Reject unauthorized user for Location without leaving fixture data behind.
|
|
BEGIN TRY
|
|
BEGIN TRANSACTION;
|
|
DECLARE @ProjectID int, @UserID int, @Source int, @Target int;
|
|
SELECT TOP (1) @ProjectID=ProjectID,@UserID=UserID FROM dbo.ProjectUserAccess WHERE IsActive=1;
|
|
INSERT dbo.Locations(ProjectID,LocationName) VALUES (@ProjectID,N'Merge validation source'); SET @Source=SCOPE_IDENTITY();
|
|
INSERT dbo.Locations(ProjectID,LocationName) VALUES (@ProjectID,N'Merge validation target'); SET @Target=SCOPE_IDENTITY();
|
|
SET @UserID=NULL;
|
|
EXEC dbo.Location_Merge @Source,@Target,@UserID;
|
|
THROW 51001, 'Invalid merge was accepted.', 1;
|
|
END TRY
|
|
BEGIN CATCH
|
|
IF XACT_STATE() <> 0 ROLLBACK TRANSACTION;
|
|
IF ERROR_NUMBER() <> 51000 THROW;
|
|
SELECT N'PASS: Location rejects unauthorized user; fixtures rolled back' AS Result;
|
|
END CATCH;
|
|
|
|
GO
|
|
-- Reject same record for StoryAsset without leaving fixture data behind.
|
|
BEGIN TRY
|
|
BEGIN TRANSACTION;
|
|
DECLARE @ProjectID int, @UserID int, @Source int, @Target int;
|
|
SELECT TOP (1) @ProjectID=ProjectID,@UserID=UserID FROM dbo.ProjectUserAccess WHERE IsActive=1;
|
|
INSERT dbo.StoryAssets(ProjectID,AssetName,AssetKindID) VALUES (@ProjectID,N'Merge validation source',(SELECT TOP (1) AssetKindID FROM dbo.AssetKinds)); SET @Source=SCOPE_IDENTITY();
|
|
INSERT dbo.StoryAssets(ProjectID,AssetName,AssetKindID) VALUES (@ProjectID,N'Merge validation target',(SELECT TOP (1) AssetKindID FROM dbo.AssetKinds)); SET @Target=SCOPE_IDENTITY();
|
|
SET @Target=@Source;
|
|
EXEC dbo.StoryAsset_Merge @Source,@Target,@UserID;
|
|
THROW 51001, 'Invalid merge was accepted.', 1;
|
|
END TRY
|
|
BEGIN CATCH
|
|
IF XACT_STATE() <> 0 ROLLBACK TRANSACTION;
|
|
IF ERROR_NUMBER() <> 51000 THROW;
|
|
SELECT N'PASS: StoryAsset rejects same record; fixtures rolled back' AS Result;
|
|
END CATCH;
|
|
|
|
GO
|
|
-- Reject archived target for StoryAsset without leaving fixture data behind.
|
|
BEGIN TRY
|
|
BEGIN TRANSACTION;
|
|
DECLARE @ProjectID int, @UserID int, @Source int, @Target int;
|
|
SELECT TOP (1) @ProjectID=ProjectID,@UserID=UserID FROM dbo.ProjectUserAccess WHERE IsActive=1;
|
|
INSERT dbo.StoryAssets(ProjectID,AssetName,AssetKindID) VALUES (@ProjectID,N'Merge validation source',(SELECT TOP (1) AssetKindID FROM dbo.AssetKinds)); SET @Source=SCOPE_IDENTITY();
|
|
INSERT dbo.StoryAssets(ProjectID,AssetName,AssetKindID) VALUES (@ProjectID,N'Merge validation target',(SELECT TOP (1) AssetKindID FROM dbo.AssetKinds)); SET @Target=SCOPE_IDENTITY();
|
|
UPDATE dbo.StoryAssets SET IsArchived=1 WHERE StoryAssetID=@Target;
|
|
EXEC dbo.StoryAsset_Merge @Source,@Target,@UserID;
|
|
THROW 51001, 'Invalid merge was accepted.', 1;
|
|
END TRY
|
|
BEGIN CATCH
|
|
IF XACT_STATE() <> 0 ROLLBACK TRANSACTION;
|
|
IF ERROR_NUMBER() <> 51000 THROW;
|
|
SELECT N'PASS: StoryAsset rejects archived target; fixtures rolled back' AS Result;
|
|
END CATCH;
|
|
|
|
GO
|
|
-- Reject other project for StoryAsset without leaving fixture data behind.
|
|
BEGIN TRY
|
|
BEGIN TRANSACTION;
|
|
DECLARE @ProjectID int, @UserID int, @Source int, @Target int;
|
|
SELECT TOP (1) @ProjectID=ProjectID,@UserID=UserID FROM dbo.ProjectUserAccess WHERE IsActive=1;
|
|
INSERT dbo.StoryAssets(ProjectID,AssetName,AssetKindID) VALUES (@ProjectID,N'Merge validation source',(SELECT TOP (1) AssetKindID FROM dbo.AssetKinds)); SET @Source=SCOPE_IDENTITY();
|
|
INSERT dbo.StoryAssets(ProjectID,AssetName,AssetKindID) VALUES (@ProjectID,N'Merge validation target',(SELECT TOP (1) AssetKindID FROM dbo.AssetKinds)); SET @Target=SCOPE_IDENTITY();
|
|
INSERT dbo.Projects(ProjectName) VALUES (N'Merge test other project');
|
|
DECLARE @OtherProjectID int=SCOPE_IDENTITY();
|
|
UPDATE dbo.StoryAssets SET ProjectID=@OtherProjectID WHERE StoryAssetID=@Target;
|
|
EXEC dbo.StoryAsset_Merge @Source,@Target,@UserID;
|
|
THROW 51001, 'Invalid merge was accepted.', 1;
|
|
END TRY
|
|
BEGIN CATCH
|
|
IF XACT_STATE() <> 0 ROLLBACK TRANSACTION;
|
|
IF ERROR_NUMBER() <> 51000 THROW;
|
|
SELECT N'PASS: StoryAsset rejects other project; fixtures rolled back' AS Result;
|
|
END CATCH;
|
|
|
|
GO
|
|
-- Reject unauthorized user for StoryAsset without leaving fixture data behind.
|
|
BEGIN TRY
|
|
BEGIN TRANSACTION;
|
|
DECLARE @ProjectID int, @UserID int, @Source int, @Target int;
|
|
SELECT TOP (1) @ProjectID=ProjectID,@UserID=UserID FROM dbo.ProjectUserAccess WHERE IsActive=1;
|
|
INSERT dbo.StoryAssets(ProjectID,AssetName,AssetKindID) VALUES (@ProjectID,N'Merge validation source',(SELECT TOP (1) AssetKindID FROM dbo.AssetKinds)); SET @Source=SCOPE_IDENTITY();
|
|
INSERT dbo.StoryAssets(ProjectID,AssetName,AssetKindID) VALUES (@ProjectID,N'Merge validation target',(SELECT TOP (1) AssetKindID FROM dbo.AssetKinds)); SET @Target=SCOPE_IDENTITY();
|
|
SET @UserID=NULL;
|
|
EXEC dbo.StoryAsset_Merge @Source,@Target,@UserID;
|
|
THROW 51001, 'Invalid merge was accepted.', 1;
|
|
END TRY
|
|
BEGIN CATCH
|
|
IF XACT_STATE() <> 0 ROLLBACK TRANSACTION;
|
|
IF ERROR_NUMBER() <> 51000 THROW;
|
|
SELECT N'PASS: StoryAsset rejects unauthorized user; fixtures rolled back' AS Result;
|
|
END CATCH;
|