mirror of
https://github.com/stashapp/stash-box.git
synced 2026-02-11 00:55:14 -06:00
522 lines
15 KiB
Go
522 lines
15 KiB
Go
//go:build integration
|
|
// +build integration
|
|
|
|
package api_test
|
|
|
|
import (
|
|
"reflect"
|
|
"testing"
|
|
|
|
"github.com/gofrs/uuid"
|
|
"github.com/stashapp/stash-box/pkg/models"
|
|
)
|
|
|
|
type studioEditTestRunner struct {
|
|
testRunner
|
|
}
|
|
|
|
func createStudioEditTestRunner(t *testing.T) *studioEditTestRunner {
|
|
return &studioEditTestRunner{
|
|
testRunner: *asAdmin(t),
|
|
}
|
|
}
|
|
|
|
func (s *studioEditTestRunner) testCreateStudioEdit() {
|
|
parentStudio, err := s.createTestStudio(nil)
|
|
if err != nil {
|
|
return
|
|
}
|
|
parentID := parentStudio.UUID()
|
|
name := "Name"
|
|
studioEditDetailsInput := models.StudioEditDetailsInput{
|
|
Name: &name,
|
|
ParentID: &parentID,
|
|
}
|
|
edit, err := s.createTestStudioEdit(models.OperationEnumCreate, &studioEditDetailsInput, nil)
|
|
if err == nil {
|
|
s.verifyCreatedStudioEdit(studioEditDetailsInput, edit)
|
|
}
|
|
}
|
|
|
|
func (s *studioEditTestRunner) verifyCreatedStudioEdit(input models.StudioEditDetailsInput, edit *models.Edit) {
|
|
r := s.resolver.Edit()
|
|
|
|
if edit.ID == uuid.Nil {
|
|
s.t.Errorf("Expected created edit id to be non-zero")
|
|
}
|
|
|
|
details, _ := r.Details(s.ctx, edit)
|
|
studioDetails := details.(*models.StudioEdit)
|
|
|
|
s.verifyEditOperation(models.OperationEnumCreate.String(), edit)
|
|
s.verifyEditStatus(models.VoteStatusEnumPending.String(), edit)
|
|
s.verifyEditTargetType(models.TargetTypeEnumStudio.String(), edit)
|
|
s.verifyEditApplication(false, edit)
|
|
|
|
// ensure basic attributes are set correctly
|
|
if *input.Name != *studioDetails.Name {
|
|
s.fieldMismatch(input.Name, studioDetails.Name, "Name")
|
|
}
|
|
|
|
if *input.ParentID != *studioDetails.ParentID {
|
|
s.fieldMismatch(*input.ParentID, *studioDetails.ParentID, "ParentID")
|
|
}
|
|
}
|
|
|
|
func (s *studioEditTestRunner) testFindEditById() {
|
|
createdEdit, err := s.createTestStudioEdit(models.OperationEnumCreate, nil, nil)
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
edit, err := s.resolver.Query().FindEdit(s.ctx, createdEdit.ID)
|
|
if err != nil {
|
|
s.t.Errorf("Error finding edit: %s", err.Error())
|
|
return
|
|
}
|
|
|
|
// ensure returned studio is not nil
|
|
if edit == nil {
|
|
s.t.Error("Did not find edit by id")
|
|
return
|
|
}
|
|
}
|
|
|
|
func (s *studioEditTestRunner) testModifyStudioEdit() {
|
|
existingParentStudio, err := s.createTestStudio(nil)
|
|
if err != nil {
|
|
return
|
|
}
|
|
existingParentID := existingParentStudio.UUID()
|
|
existingName := "studioName"
|
|
studioCreateInput := models.StudioCreateInput{
|
|
Name: existingName,
|
|
ParentID: &existingParentID,
|
|
}
|
|
createdStudio, err := s.createTestStudio(&studioCreateInput)
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
newParent, err := s.createTestStudio(nil)
|
|
if err != nil {
|
|
return
|
|
}
|
|
newParentID := newParent.UUID()
|
|
newName := "newName"
|
|
|
|
site, err := s.createTestSite(nil)
|
|
if err != nil {
|
|
return
|
|
}
|
|
url := models.URLInput{
|
|
URL: "http://example.org",
|
|
SiteID: site.ID,
|
|
}
|
|
studioEditDetailsInput := models.StudioEditDetailsInput{
|
|
Name: &newName,
|
|
ParentID: &newParentID,
|
|
Urls: []*models.URLInput{&url},
|
|
}
|
|
id := createdStudio.UUID()
|
|
editInput := models.EditInput{
|
|
Operation: models.OperationEnumModify,
|
|
ID: &id,
|
|
}
|
|
|
|
createdUpdateEdit, err := s.createTestStudioEdit(models.OperationEnumModify, &studioEditDetailsInput, &editInput)
|
|
|
|
s.verifyUpdatedStudioEdit(createdStudio, studioEditDetailsInput, createdUpdateEdit)
|
|
}
|
|
|
|
func (s *studioEditTestRunner) verifyUpdatedStudioEdit(originalStudio *studioOutput, input models.StudioEditDetailsInput, edit *models.Edit) {
|
|
studioDetails := s.getEditStudioDetails(edit)
|
|
|
|
s.verifyEditOperation(models.OperationEnumModify.String(), edit)
|
|
s.verifyEditStatus(models.VoteStatusEnumPending.String(), edit)
|
|
s.verifyEditTargetType(models.TargetTypeEnumStudio.String(), edit)
|
|
s.verifyEditApplication(false, edit)
|
|
|
|
// ensure basic attributes are set correctly
|
|
if *input.Name != *studioDetails.Name {
|
|
s.fieldMismatch(*input.Name, *studioDetails.Name, "Name")
|
|
}
|
|
|
|
if *input.ParentID != *studioDetails.ParentID {
|
|
s.fieldMismatch(*input.ParentID, *studioDetails.ParentID, "ParentID")
|
|
}
|
|
|
|
s.compareURLs(input.Urls, studioDetails.AddedUrls)
|
|
}
|
|
|
|
func (s *studioEditTestRunner) testDestroyStudioEdit() {
|
|
createdStudio, err := s.createTestStudio(nil)
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
studioID := createdStudio.UUID()
|
|
|
|
studioEditDetailsInput := models.StudioEditDetailsInput{}
|
|
editInput := models.EditInput{
|
|
Operation: models.OperationEnumDestroy,
|
|
ID: &studioID,
|
|
}
|
|
destroyEdit, err := s.createTestStudioEdit(models.OperationEnumDestroy, &studioEditDetailsInput, &editInput)
|
|
|
|
s.verifyDestroyStudioEdit(studioID, destroyEdit)
|
|
}
|
|
|
|
func (s *studioEditTestRunner) verifyDestroyStudioEdit(studioID uuid.UUID, edit *models.Edit) {
|
|
s.verifyEditOperation(models.OperationEnumDestroy.String(), edit)
|
|
s.verifyEditStatus(models.VoteStatusEnumPending.String(), edit)
|
|
s.verifyEditTargetType(models.TargetTypeEnumStudio.String(), edit)
|
|
s.verifyEditApplication(false, edit)
|
|
|
|
editTarget := s.getEditStudioTarget(edit)
|
|
|
|
if studioID != editTarget.ID {
|
|
s.fieldMismatch(studioID, editTarget.ID.String(), "ID")
|
|
}
|
|
}
|
|
|
|
func (s *studioEditTestRunner) testMergeStudioEdit() {
|
|
existingName := "studioName2"
|
|
studioCreateInput := models.StudioCreateInput{
|
|
Name: existingName,
|
|
}
|
|
createdPrimaryStudio, err := s.createTestStudio(&studioCreateInput)
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
createdMergeStudio, err := s.createTestStudio(nil)
|
|
|
|
newName := "newName2"
|
|
studioEditDetailsInput := models.StudioEditDetailsInput{
|
|
Name: &newName,
|
|
}
|
|
id := createdPrimaryStudio.UUID()
|
|
mergeSources := []uuid.UUID{createdMergeStudio.UUID()}
|
|
editInput := models.EditInput{
|
|
Operation: models.OperationEnumMerge,
|
|
ID: &id,
|
|
MergeSourceIds: mergeSources,
|
|
}
|
|
|
|
createdMergeEdit, err := s.createTestStudioEdit(models.OperationEnumMerge, &studioEditDetailsInput, &editInput)
|
|
|
|
s.verifyMergeStudioEdit(createdPrimaryStudio, studioEditDetailsInput, createdMergeEdit, mergeSources)
|
|
}
|
|
|
|
func (s *studioEditTestRunner) verifyMergeStudioEdit(originalStudio *studioOutput, input models.StudioEditDetailsInput, edit *models.Edit, inputMergeSources []uuid.UUID) {
|
|
studioDetails := s.getEditStudioDetails(edit)
|
|
|
|
s.verifyEditOperation(models.OperationEnumMerge.String(), edit)
|
|
s.verifyEditStatus(models.VoteStatusEnumPending.String(), edit)
|
|
s.verifyEditTargetType(models.TargetTypeEnumStudio.String(), edit)
|
|
s.verifyEditApplication(false, edit)
|
|
|
|
// ensure basic attributes are set correctly
|
|
if *input.Name != *studioDetails.Name {
|
|
s.fieldMismatch(*input.Name, *studioDetails.Name, "Name")
|
|
}
|
|
|
|
var mergeSources []uuid.UUID
|
|
merges, _ := s.resolver.Edit().MergeSources(s.ctx, edit)
|
|
for i := range merges {
|
|
merge := merges[i].(*models.Studio)
|
|
mergeSources = append(mergeSources, merge.ID)
|
|
}
|
|
if !reflect.DeepEqual(inputMergeSources, mergeSources) {
|
|
s.fieldMismatch(inputMergeSources, mergeSources, "MergeSources")
|
|
}
|
|
}
|
|
|
|
func (s *studioEditTestRunner) testApplyCreateStudioEdit() {
|
|
name := "Name"
|
|
parent, err := s.createTestStudio(nil)
|
|
if err != nil {
|
|
return
|
|
}
|
|
parentID := parent.UUID()
|
|
studioEditDetailsInput := models.StudioEditDetailsInput{
|
|
Name: &name,
|
|
ParentID: &parentID,
|
|
}
|
|
edit, err := s.createTestStudioEdit(models.OperationEnumCreate, &studioEditDetailsInput, nil)
|
|
appliedEdit, err := s.applyEdit(edit.ID)
|
|
if err == nil {
|
|
s.verifyAppliedStudioCreateEdit(studioEditDetailsInput, appliedEdit)
|
|
}
|
|
}
|
|
|
|
func (s *studioEditTestRunner) verifyAppliedStudioCreateEdit(input models.StudioEditDetailsInput, edit *models.Edit) {
|
|
if edit.ID == uuid.Nil {
|
|
s.t.Errorf("Expected created edit id to be non-zero")
|
|
}
|
|
|
|
s.verifyEditOperation(models.OperationEnumCreate.String(), edit)
|
|
s.verifyEditStatus(models.VoteStatusEnumImmediateAccepted.String(), edit)
|
|
s.verifyEditTargetType(models.TargetTypeEnumStudio.String(), edit)
|
|
s.verifyEditApplication(true, edit)
|
|
|
|
studio := s.getEditStudioTarget(edit)
|
|
|
|
// ensure basic attributes are set correctly
|
|
if *input.Name != studio.Name {
|
|
s.fieldMismatch(input.Name, studio.Name, "Name")
|
|
}
|
|
|
|
if *input.ParentID != studio.ParentStudioID.UUID {
|
|
s.fieldMismatch(*input.ParentID, studio.ParentStudioID.UUID.String(), "ParentID")
|
|
}
|
|
}
|
|
|
|
func (s *studioEditTestRunner) testApplyModifyStudioEdit() {
|
|
existingName := "studioName3"
|
|
site, err := s.createTestSite(nil)
|
|
if err != nil {
|
|
return
|
|
}
|
|
studioCreateInput := models.StudioCreateInput{
|
|
Name: existingName,
|
|
Urls: []*models.URLInput{{
|
|
URL: "http://example.org/old",
|
|
SiteID: site.ID,
|
|
}},
|
|
}
|
|
createdStudio, err := s.createTestStudio(&studioCreateInput)
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
newName := "newName3"
|
|
newParent, err := s.createTestStudio(nil)
|
|
if err != nil {
|
|
return
|
|
}
|
|
newParentID := newParent.UUID()
|
|
newUrl := models.URLInput{
|
|
URL: "http://example.org/new",
|
|
SiteID: site.ID,
|
|
}
|
|
studioEditDetailsInput := models.StudioEditDetailsInput{
|
|
Name: &newName,
|
|
ParentID: &newParentID,
|
|
Urls: []*models.URLInput{&newUrl},
|
|
}
|
|
id := createdStudio.UUID()
|
|
editInput := models.EditInput{
|
|
Operation: models.OperationEnumModify,
|
|
ID: &id,
|
|
}
|
|
|
|
createdUpdateEdit, err := s.createTestStudioEdit(models.OperationEnumModify, &studioEditDetailsInput, &editInput)
|
|
if err != nil {
|
|
return
|
|
}
|
|
appliedEdit, err := s.applyEdit(createdUpdateEdit.ID)
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
modifiedStudio, _ := s.resolver.Query().FindStudio(s.ctx, &id, nil)
|
|
s.verifyApplyModifyStudioEdit(studioEditDetailsInput, modifiedStudio, appliedEdit)
|
|
}
|
|
|
|
func (s *studioEditTestRunner) verifyApplyModifyStudioEdit(input models.StudioEditDetailsInput, updatedStudio *models.Studio, edit *models.Edit) {
|
|
s.verifyEditOperation(models.OperationEnumModify.String(), edit)
|
|
s.verifyEditStatus(models.VoteStatusEnumImmediateAccepted.String(), edit)
|
|
s.verifyEditTargetType(models.TargetTypeEnumStudio.String(), edit)
|
|
s.verifyEditApplication(true, edit)
|
|
|
|
// ensure basic attributes are set correctly
|
|
if *input.Name != updatedStudio.Name {
|
|
s.fieldMismatch(*input.Name, updatedStudio.Name, "Name")
|
|
}
|
|
|
|
if !updatedStudio.ParentStudioID.Valid || *input.ParentID != updatedStudio.ParentStudioID.UUID {
|
|
s.fieldMismatch(*input.ParentID, updatedStudio.ParentStudioID.UUID.String(), "ParentStudioID")
|
|
}
|
|
|
|
urls, _ := s.resolver.Studio().Urls(s.ctx, updatedStudio)
|
|
s.compareURLs(input.Urls, urls)
|
|
}
|
|
|
|
func (s *studioEditTestRunner) testApplyDestroyStudioEdit() {
|
|
createdStudio, err := s.createTestStudio(nil)
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
studioID := createdStudio.UUID()
|
|
sceneInput := models.SceneCreateInput{
|
|
StudioID: &studioID,
|
|
Date: "2020-03-02",
|
|
}
|
|
scene, _ := s.createTestScene(&sceneInput)
|
|
|
|
studioEditDetailsInput := models.StudioEditDetailsInput{}
|
|
editInput := models.EditInput{
|
|
Operation: models.OperationEnumDestroy,
|
|
ID: &studioID,
|
|
}
|
|
destroyEdit, err := s.createTestStudioEdit(models.OperationEnumDestroy, &studioEditDetailsInput, &editInput)
|
|
if err != nil {
|
|
return
|
|
}
|
|
appliedEdit, err := s.applyEdit(destroyEdit.ID)
|
|
|
|
destroyedStudio, _ := s.resolver.Query().FindStudio(s.ctx, &studioID, nil)
|
|
scene, _ = s.client.findScene(scene.UUID())
|
|
s.verifyApplyDestroyStudioEdit(destroyedStudio, appliedEdit, scene)
|
|
}
|
|
|
|
func (s *studioEditTestRunner) verifyApplyDestroyStudioEdit(destroyedStudio *models.Studio, edit *models.Edit, scene *sceneOutput) {
|
|
s.verifyEditOperation(models.OperationEnumDestroy.String(), edit)
|
|
s.verifyEditStatus(models.VoteStatusEnumImmediateAccepted.String(), edit)
|
|
s.verifyEditTargetType(models.TargetTypeEnumStudio.String(), edit)
|
|
s.verifyEditApplication(true, edit)
|
|
|
|
if destroyedStudio.Deleted != true {
|
|
s.fieldMismatch(destroyedStudio.Deleted, true, "Deleted")
|
|
}
|
|
|
|
if scene.Studio != nil {
|
|
s.fieldMismatch(scene.Studio, nil, "Scene studio")
|
|
}
|
|
}
|
|
|
|
func (s *studioEditTestRunner) testApplyMergeStudioEdit() {
|
|
mergeSource1, err := s.createTestStudio(nil)
|
|
if err != nil {
|
|
return
|
|
}
|
|
mergeSource2, err := s.createTestStudio(nil)
|
|
if err != nil {
|
|
return
|
|
}
|
|
mergeTarget, err := s.createTestStudio(nil)
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
// Scene with studio from both source and target, should not cause db unique error
|
|
mergeTargetID := mergeTarget.UUID()
|
|
sceneInput := models.SceneCreateInput{
|
|
StudioID: &mergeTargetID,
|
|
Date: "2020-03-02",
|
|
}
|
|
scene1, err := s.createTestScene(&sceneInput)
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
mergeSource1ID := mergeSource1.UUID()
|
|
sceneInput = models.SceneCreateInput{
|
|
StudioID: &mergeSource1ID,
|
|
Date: "2020-03-02",
|
|
}
|
|
scene2, err := s.createTestScene(&sceneInput)
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
newName := "newName4"
|
|
studioEditDetailsInput := models.StudioEditDetailsInput{
|
|
Name: &newName,
|
|
}
|
|
id := mergeTarget.UUID()
|
|
mergeSources := []uuid.UUID{mergeSource1.UUID(), mergeSource2.UUID()}
|
|
editInput := models.EditInput{
|
|
Operation: models.OperationEnumMerge,
|
|
ID: &id,
|
|
MergeSourceIds: mergeSources,
|
|
}
|
|
|
|
mergeEdit, err := s.createTestStudioEdit(models.OperationEnumMerge, &studioEditDetailsInput, &editInput)
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
appliedMerge, err := s.applyEdit(mergeEdit.ID)
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
scene1, _ = s.client.findScene(scene1.UUID())
|
|
scene2, _ = s.client.findScene(scene2.UUID())
|
|
|
|
s.verifyAppliedMergeStudioEdit(studioEditDetailsInput, appliedMerge, scene1, scene2)
|
|
}
|
|
|
|
func (s *studioEditTestRunner) verifyAppliedMergeStudioEdit(input models.StudioEditDetailsInput, edit *models.Edit, scene1 *sceneOutput, scene2 *sceneOutput) {
|
|
s.verifyEditOperation(models.OperationEnumMerge.String(), edit)
|
|
s.verifyEditStatus(models.VoteStatusEnumImmediateAccepted.String(), edit)
|
|
s.verifyEditTargetType(models.TargetTypeEnumStudio.String(), edit)
|
|
s.verifyEditApplication(true, edit)
|
|
|
|
studioDetails := s.getEditStudioDetails(edit)
|
|
if *input.Name != *studioDetails.Name {
|
|
s.fieldMismatch(*input.Name, *studioDetails.Name, "Name")
|
|
}
|
|
|
|
merges, _ := s.resolver.Edit().MergeSources(s.ctx, edit)
|
|
for i := range merges {
|
|
studio := merges[i].(*models.Studio)
|
|
if studio.Deleted != true {
|
|
s.fieldMismatch(studio.Deleted, true, "Deleted")
|
|
}
|
|
}
|
|
|
|
editTarget := s.getEditStudioTarget(edit)
|
|
if scene1.Studio.ID != editTarget.ID.String() {
|
|
s.fieldMismatch(scene1.Studio.ID, editTarget.ID, "Scene 1 studio ID")
|
|
}
|
|
|
|
if scene2.Studio.ID != editTarget.ID.String() {
|
|
s.fieldMismatch(scene2.Studio.ID, editTarget.ID, "Scene 2 studio ID")
|
|
}
|
|
}
|
|
|
|
func TestCreateStudioEdit(t *testing.T) {
|
|
pt := createStudioEditTestRunner(t)
|
|
pt.testCreateStudioEdit()
|
|
}
|
|
|
|
func TestModifyStudioEdit(t *testing.T) {
|
|
pt := createStudioEditTestRunner(t)
|
|
pt.testModifyStudioEdit()
|
|
}
|
|
|
|
func TestDestroyStudioEdit(t *testing.T) {
|
|
pt := createStudioEditTestRunner(t)
|
|
pt.testDestroyStudioEdit()
|
|
}
|
|
|
|
func TestMergeStudioEdit(t *testing.T) {
|
|
pt := createStudioEditTestRunner(t)
|
|
pt.testMergeStudioEdit()
|
|
}
|
|
|
|
func TestApplyCreateStudioEdit(t *testing.T) {
|
|
pt := createStudioEditTestRunner(t)
|
|
pt.testApplyCreateStudioEdit()
|
|
}
|
|
|
|
func TestApplyModifyStudioEdit(t *testing.T) {
|
|
pt := createStudioEditTestRunner(t)
|
|
pt.testApplyModifyStudioEdit()
|
|
}
|
|
|
|
func TestApplyDestroyStudioEdit(t *testing.T) {
|
|
pt := createStudioEditTestRunner(t)
|
|
pt.testApplyDestroyStudioEdit()
|
|
}
|
|
|
|
func TestApplyMergeStudioEdit(t *testing.T) {
|
|
pt := createStudioEditTestRunner(t)
|
|
pt.testApplyMergeStudioEdit()
|
|
}
|