diff --git a/api/graphql/generated.go b/api/graphql/generated.go index 58554ec2..63ad314a 100644 --- a/api/graphql/generated.go +++ b/api/graphql/generated.go @@ -1947,7 +1947,7 @@ type Album { shares: [ShareToken!]! - coverID: Int! + coverID: Int } type MediaURL { @@ -3362,14 +3362,11 @@ func (ec *executionContext) _Album_coverID(ctx context.Context, field graphql.Co return graphql.Null } if resTmp == nil { - if !graphql.HasFieldError(ctx, fc) { - ec.Errorf(ctx, "must not be null") - } return graphql.Null } res := resTmp.(*int) fc.Result = res - return ec.marshalNInt2ᚖint(ctx, field.Selections, res) + return ec.marshalOInt2ᚖint(ctx, field.Selections, res) } func (ec *executionContext) _AuthorizeResult_success(ctx context.Context, field graphql.CollectedField, obj *models.AuthorizeResult) (ret graphql.Marshaler) { @@ -10366,9 +10363,6 @@ func (ec *executionContext) _Album(ctx context.Context, sel ast.SelectionSet, ob }) case "coverID": out.Values[i] = ec._Album_coverID(ctx, field, obj) - if out.Values[i] == graphql.Null { - atomic.AddUint32(&invalids, 1) - } default: panic("unknown field " + strconv.Quote(field.Name)) } @@ -12238,27 +12232,6 @@ func (ec *executionContext) marshalNInt2int64(ctx context.Context, sel ast.Selec return res } -func (ec *executionContext) unmarshalNInt2ᚖint(ctx context.Context, v interface{}) (*int, error) { - res, err := graphql.UnmarshalInt(v) - return &res, graphql.ErrorOnPath(ctx, err) -} - -func (ec *executionContext) marshalNInt2ᚖint(ctx context.Context, sel ast.SelectionSet, v *int) graphql.Marshaler { - if v == nil { - if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { - ec.Errorf(ctx, "must not be null") - } - return graphql.Null - } - res := graphql.MarshalInt(*v) - if res == graphql.Null { - if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { - ec.Errorf(ctx, "must not be null") - } - } - return res -} - func (ec *executionContext) marshalNMedia2githubᚗcomᚋphotoviewᚋphotoviewᚋapiᚋgraphqlᚋmodelsᚐMedia(ctx context.Context, sel ast.SelectionSet, v models.Media) graphql.Marshaler { return ec._Media(ctx, sel, &v) } diff --git a/api/graphql/resolvers/album_test.go b/api/graphql/resolvers/album_test.go index b5457574..859d5aab 100644 --- a/api/graphql/resolvers/album_test.go +++ b/api/graphql/resolvers/album_test.go @@ -1,6 +1,7 @@ package resolvers_test import ( + "context" "testing" api "github.com/photoview/photoview/api/graphql" @@ -9,13 +10,22 @@ import ( "github.com/99designs/gqlgen/client" "github.com/99designs/gqlgen/graphql/handler" + "github.com/photoview/photoview/api/graphql/auth" "github.com/photoview/photoview/api/test_utils" "github.com/stretchr/testify/assert" ) +func addContext(ctx context.Context) client.Option { + return func(bd *client.Request) { + bd.HTTP = bd.HTTP.WithContext(ctx) + } +} + func TestAlbumCover(t *testing.T) { db := test_utils.DatabaseTest(t) + TestCoverID := 6 + rootAlbum := models.Album{ Title: "root", Path: "/photos", @@ -25,8 +35,6 @@ func TestAlbumCover(t *testing.T) { return } - TestCoverID := 6 - children := []models.Album{ { Title: "child1", @@ -49,32 +57,32 @@ func TestAlbumCover(t *testing.T) { { Title: "pic1", Path: "/photos/pic1", - AlbumID: &rootAlbum.ID, + AlbumID: rootAlbum.ID, }, { Title: "pic2", Path: "/photos/pic2", - AlbumID: &rootAlbum.ID, + AlbumID: rootAlbum.ID, }, { Title: "pic3", Path: "/photos/child1/pic3", - AlbumID: &children[0].ID, + AlbumID: children[0].ID, }, { Title: "pic4", Path: "/photos/child1/pic4", - AlbumID: &children[0].ID, + AlbumID: children[0].ID, }, { Title: "pic5", Path: "/photos/child2/pic5", - AlbumID: &children[1].ID, + AlbumID: children[1].ID, }, { Title: "pic6", Path: "/photos/child2/pic6", - AlbumID: &children[1].ID, + AlbumID: children[1].ID, }, } @@ -82,192 +90,120 @@ func TestAlbumCover(t *testing.T) { return } - verifyResult := func(t *testing.T, expected_media []*models.Media, result []*models.Media) { - assert.Equal(t, len(expected_media), len(result)) - - for _, expected := range expected_media { - found_expected := false - for _, item := range result { - if item.Title == expected.Title && item.Path == expected.Path && item.AlbumID == expected.AlbumID { - found_expected = true - break - } - } - if !found_expected { - assert.Failf(t, "media did not match", "expected to find item: %v", expected) - } - } + pass := "" + regularUser := models.User{ + Username: "user1", + Password: &pass, + Admin: false, } - // - c := client.New(handler.NewDefaultServer(api.NewExecutableSchema(api.Config{Resolvers: &resolvers.Resolver{ - Database: db, - }}))) + if !assert.NoError(t, db.Save(®ularUser).Error) { + return + } + + if !assert.NoError(t, db.Model(®ularUser).Association("Albums").Append(&rootAlbum)) { + return + } + + if !assert.NoError(t, db.Model(®ularUser).Association("Albums").Append(&children)) { + return + } + + ctx := auth.AddUserToContext(context.TODO(), ®ularUser) + + c := client.New(handler.NewDefaultServer(api.NewExecutableSchema(api.Config{ + Resolvers: &resolvers.Resolver{ + Database: db, + }, + Directives: api.DirectiveRoot{ + IsAuthorized: api.IsAuthorized, + }, + }))) t.Run("Album get cover photos", func(t *testing.T) { - var resp []*models.Media - - c.MustPost(`query { Thumbnail( album(id:1)) { - Title, Path, AlbumID - }}`, &resp[0]) - c.MustPost(`query { Thumbnail( album(id:1)) { - Title, Path, AlbumID - }}`, &resp[1]) - c.MustPost(`query { Thumbnail( album(id:1)) { - Title, Path, AlbumID - }}`, &resp[2]) - - expected_thumbnails := []*models.Media{ - { - Title: "pic1", - Path: "/photos/pic1", - AlbumID: 1, - }, - { - Title: "pic3", - Path: "/photos/child1/pic3", - AlbumID: 2, - }, - { - Title: "pic6", - Path: "/photos/child2/pic6", - AlbumID: 3, - }, + var resp struct { + Album struct { + Thumbnail struct { + Title string + } + } } - verifyResult(t, expected_thumbnails, resp) + q := `query ($albumID: ID!){ album (id: $albumID) { + thumbnail { + title + } + }} + ` + + postErr := c.Post( + q, + &resp, + client.Var("albumID", &children[1].ID), + addContext(ctx), + ) + if !assert.NoError(t, postErr) { + return + } + + assert.EqualValues(t, "pic6", resp.Album.Thumbnail.Title) + }) + + t.Run("Album reset cover photos", func(t *testing.T) { + + var resp struct { + ResetAlbumCover struct { + CoverID int + } + } + + q := `mutation resetCover($albumID: ID!) { + resetAlbumCover(albumID: $albumID) { + coverID + } + } + ` + postErr := c.Post( + q, + &resp, + client.Var("albumID", &children[1].ID), + addContext(ctx), + ) + if !assert.NoError(t, postErr) { + return + } + + assert.EqualValues(t, 0, resp.ResetAlbumCover.CoverID) }) t.Run("Album change cover photos", func(t *testing.T) { - var resp []*models.Media - - c.MustPost(`query { Thumbnail( album(id:1)) { - Title, Path, AlbumID - }}`, &resp[0]) - c.MustPost(`query { Thumbnail( album(id:1)) { - Title, Path, AlbumID - }}`, &resp[1]) - c.MustPost(`query { Thumbnail( album(id:1)) { - Title, Path, AlbumID - }}`, &resp[2]) - - expected_thumbnails := []*models.Media{ - { - Title: "pic1", - Path: "/photos/pic1", - AlbumID: 1, - }, - { - Title: "pic3", - Path: "/photos/child1/pic3", - AlbumID: 2, - }, - { - Title: "pic6", - Path: "/photos/child2/pic6", - AlbumID: 3, - }, + var resp struct { + SetAlbumCover struct { + CoverID int + } } - verifyResult(t, expected_thumbnails, resp) + q := `mutation changeCover($coverID: ID!) { + setAlbumCover(coverID: $coverID) { + coverID, + } + } + ` + + postErr := c.Post( + q, + &resp, + client.Var("coverID", &photos[1].ID), + addContext(ctx), + ) + if !assert.NoError(t, postErr) { + return + } + + assert.EqualValues(t, &photos[1].ID, &resp.SetAlbumCover.CoverID) + }) } - -// -// -// func (r *albumResolver) Thumbnail(ctx context.Context, obj *models.Album) (*models.Media, error) { -// -// var media models.Media -// -// fmt.Print(obj.CoverID) -// -// if obj.CoverID == nil { -// if err := r.Database.Raw(` -// WITH recursive sub_albums AS ( -// SELECT * FROM albums AS root WHERE id = ? -// UNION ALL -// SELECT child.* FROM albums AS child JOIN sub_albums ON child.parent_album_id = sub_albums.id -// ) -// -// SELECT * FROM media WHERE media.album_id IN ( -// SELECT id FROM sub_albums -// ) AND media.id IN ( -// SELECT media_id FROM media_urls WHERE media_urls.media_id = media.id -// ) LIMIT 1 -// `, obj.ID).Find(&media).Error; err != nil { -// return nil, err -// } -// } else { -// if err := r.Database.Where("id = ?", obj.CoverID).Find(&media).Error; err != nil { -// return nil, err -// } -// } -// -// return &media, nil -// } -// -// // Takes album_id, resets album.cover_id to 0 (null) -// func (r *mutationResolver) ResetAlbumCover(ctx context.Context, albumID int) (*models.Album, error) { -// user := auth.UserFromContext(ctx) -// if user == nil { -// return nil, errors.New("unauthorized") -// } -// -// var album models.Album -// if err := r.Database.Find(&album, albumID).Error; err != nil { -// return nil, err -// } -// -// ownsAlbum, err := user.OwnsAlbum(r.Database, &album) -// if err != nil { -// return nil, err -// } -// -// if !ownsAlbum { -// return nil, errors.New("forbidden") -// } -// -// if err := r.Database.Model(&album).Update("cover_id", nil).Error; err != nil { -// return nil, err -// } -// -// return &album, nil -// } -// -// // Takes media.id, finds parent album, sets album.cover_id to media.id (must be a more efficient way of doing this, but it works) -// func (r *mutationResolver) SetAlbumCover(ctx context.Context, coverID int) (*models.Album, error) { -// user := auth.UserFromContext(ctx) -// if user == nil { -// return nil, errors.New("unauthorized") -// } -// -// var media models.Media -// -// if err := r.Database.Find(&media, coverID).Error; err != nil { -// return nil, err -// } -// -// var album models.Album -// -// if err := r.Database.Find(&album, &media.AlbumID).Error; err != nil { -// return nil, err -// } -// -// ownsAlbum, err := user.OwnsAlbum(r.Database, &album) -// if err != nil { -// return nil, err -// } -// -// if !ownsAlbum { -// return nil, errors.New("forbidden") -// } -// -// if err := r.Database.Model(&album).Update("cover_id", coverID).Error; err != nil { -// return nil, err -// } -// -// return &album, nil -// } diff --git a/api/graphql/schema.graphql b/api/graphql/schema.graphql index f765eafd..b9cbbcee 100644 --- a/api/graphql/schema.graphql +++ b/api/graphql/schema.graphql @@ -279,7 +279,7 @@ type Album { shares: [ShareToken!]! - coverID: Int! + coverID: Int } type MediaURL {