mirror of
https://github.com/hanzoai/forge.git
synced 2026-10-30 15:00:39 +00:00
2978 files. The fork is 2026-07-15 (rebrand: gitea.dev -> github.com/hanzoai/git), so 2026 is the year, and "Copyright 2026 Hanzo AI, Inc." was already the form used by the handful of files that had ours. Shape is now: // Copyright 2026 Hanzo AI, Inc. All rights reserved. // Copyright 2015 The Gogs Authors. All rights reserved. // Copyright 2019 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT Ours on top, theirs retained verbatim. Retained because MIT requires it, and separately because they are true — those authors did write that code. Not renamed to "The Git Authors": Git is a different project under a different license, and putting its name here would attribute this code to people who have nothing to do with it. Adding our line is the fix; overwriting theirs would have been both a licence violation and a false statement. gofmt still reports import-order drift in some of these files. It predates this change (verified against a stash) and is left alone rather than burying a one-line-per-file legal change under 3000 files of unrelated reordering. Build clean. Co-authored-by: Hanzo Dev <[email protected]>
187 lines
6.4 KiB
Go
187 lines
6.4 KiB
Go
// Copyright 2026 Hanzo AI, Inc. All rights reserved.
|
|
// Copyright 2026 The Gitea Authors. All rights reserved.
|
|
// SPDX-License-Identifier: MIT
|
|
|
|
package user_test
|
|
|
|
import (
|
|
"testing"
|
|
|
|
"github.com/hanzoai/git/models/db"
|
|
"github.com/hanzoai/git/models/unittest"
|
|
user_model "github.com/hanzoai/git/models/user"
|
|
"github.com/hanzoai/git/modules/util"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
)
|
|
|
|
func TestBadge(t *testing.T) {
|
|
assert.NoError(t, unittest.PrepareTestDatabase())
|
|
|
|
t.Run("GetBadgeNotExist", testGetBadgeNotExist)
|
|
t.Run("CreateBadgeAlreadyExists", testCreateBadgeAlreadyExists)
|
|
t.Run("GetBadgeUsers", testGetBadgeUsers)
|
|
t.Run("AddAndRemoveUserBadges", testAddAndRemoveUserBadges)
|
|
t.Run("SearchBadgesOrderingAndKeyword", testSearchBadgesOrderingAndKeyword)
|
|
}
|
|
|
|
func testGetBadgeNotExist(t *testing.T) {
|
|
badge, err := user_model.GetBadge(t.Context(), "does-not-exist")
|
|
assert.Nil(t, badge)
|
|
assert.Error(t, err)
|
|
assert.ErrorIs(t, err, util.ErrNotExist)
|
|
}
|
|
|
|
func testCreateBadgeAlreadyExists(t *testing.T) {
|
|
badge := &user_model.Badge{
|
|
Slug: "duplicate-badge-slug",
|
|
Description: "First",
|
|
}
|
|
assert.NoError(t, user_model.CreateBadge(t.Context(), badge))
|
|
|
|
err := user_model.CreateBadge(t.Context(), &user_model.Badge{
|
|
Slug: "duplicate-badge-slug",
|
|
Description: "Second",
|
|
})
|
|
assert.Error(t, err)
|
|
assert.ErrorIs(t, err, util.ErrAlreadyExist)
|
|
}
|
|
|
|
func testGetBadgeUsers(t *testing.T) {
|
|
// Create a test badge
|
|
badge := &user_model.Badge{
|
|
Slug: "test-badge-users",
|
|
Description: "Test Badge",
|
|
ImageURL: "test.png",
|
|
}
|
|
assert.NoError(t, user_model.CreateBadge(t.Context(), badge))
|
|
|
|
// Create test users and assign badges
|
|
user1 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1})
|
|
user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
|
|
|
|
assert.NoError(t, user_model.AddUserBadge(t.Context(), user1, badge))
|
|
assert.NoError(t, user_model.AddUserBadge(t.Context(), user2, badge))
|
|
defer func() {
|
|
assert.NoError(t, user_model.RemoveUserBadge(t.Context(), user1, badge))
|
|
assert.NoError(t, user_model.RemoveUserBadge(t.Context(), user2, badge))
|
|
}()
|
|
|
|
// Test getting users with pagination
|
|
opts := &user_model.GetBadgeUsersOptions{
|
|
BadgeSlug: badge.Slug,
|
|
ListOptions: db.ListOptions{
|
|
Page: 1,
|
|
PageSize: 1,
|
|
},
|
|
}
|
|
|
|
users, count, err := user_model.GetBadgeUsers(t.Context(), opts)
|
|
assert.NoError(t, err)
|
|
assert.EqualValues(t, 2, count)
|
|
assert.Len(t, users, 1)
|
|
|
|
// Test second page
|
|
opts.Page = 2
|
|
users, count, err = user_model.GetBadgeUsers(t.Context(), opts)
|
|
assert.NoError(t, err)
|
|
assert.EqualValues(t, 2, count)
|
|
assert.Len(t, users, 1)
|
|
|
|
// Test with non-existent badge
|
|
opts.BadgeSlug = "non-existent"
|
|
users, count, err = user_model.GetBadgeUsers(t.Context(), opts)
|
|
assert.NoError(t, err)
|
|
assert.EqualValues(t, 0, count)
|
|
assert.Empty(t, users)
|
|
}
|
|
|
|
func testAddAndRemoveUserBadges(t *testing.T) {
|
|
badge1 := unittest.AssertExistsAndLoadBean(t, &user_model.Badge{ID: 1})
|
|
user1 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1})
|
|
|
|
// Add a badge to user and verify that it is returned in the list
|
|
assert.NoError(t, user_model.AddUserBadge(t.Context(), user1, badge1))
|
|
badges, count, err := user_model.GetUserBadges(t.Context(), user1)
|
|
assert.Equal(t, int64(1), count)
|
|
assert.Equal(t, badge1.Slug, badges[0].Slug)
|
|
assert.NoError(t, err)
|
|
|
|
// Confirm that it is impossible to duplicate the same badge
|
|
err = user_model.AddUserBadge(t.Context(), user1, badge1)
|
|
assert.Error(t, err)
|
|
assert.ErrorIs(t, err, util.ErrAlreadyExist)
|
|
|
|
// Nothing happened to the existing badge
|
|
badges, count, err = user_model.GetUserBadges(t.Context(), user1)
|
|
assert.Equal(t, int64(1), count)
|
|
assert.Equal(t, badge1.Slug, badges[0].Slug)
|
|
assert.NoError(t, err)
|
|
|
|
// Remove a badge from user and verify that it is no longer in the list
|
|
assert.NoError(t, user_model.RemoveUserBadge(t.Context(), user1, badge1))
|
|
_, count, err = user_model.GetUserBadges(t.Context(), user1)
|
|
assert.Equal(t, int64(0), count)
|
|
assert.NoError(t, err)
|
|
|
|
// Removing empty or missing badge selections should be a no-op.
|
|
assert.NoError(t, user_model.RemoveUserBadges(t.Context(), user1, nil))
|
|
assert.NoError(t, user_model.RemoveUserBadges(t.Context(), user1, []*user_model.Badge{{Slug: "does-not-exist"}}))
|
|
}
|
|
|
|
func testSearchBadgesOrderingAndKeyword(t *testing.T) {
|
|
createdBadges := []*user_model.Badge{
|
|
{Slug: "badge-sort-b", Description: "Badge Sort B"},
|
|
{Slug: "badge-sort-c", Description: "Badge Sort C"},
|
|
{Slug: "badge-sort-a", Description: "Badge Sort A"},
|
|
{Slug: "badge-sort-case", Description: "MiXeDCaSeKeyword"},
|
|
}
|
|
for _, badge := range createdBadges {
|
|
assert.NoError(t, user_model.CreateBadge(t.Context(), badge))
|
|
}
|
|
|
|
opts := &user_model.SearchBadgeOptions{
|
|
ListOptions: db.ListOptions{ListAll: true},
|
|
Keyword: "badge-sort-",
|
|
OrderBy: db.SearchOrderBy("`badge`.id ASC"),
|
|
}
|
|
|
|
oldestFirst, count, err := user_model.SearchBadges(t.Context(), opts)
|
|
assert.NoError(t, err)
|
|
assert.EqualValues(t, 4, count)
|
|
assert.Equal(t, []string{"badge-sort-b", "badge-sort-c", "badge-sort-a", "badge-sort-case"}, collectBadgeSlugs(oldestFirst))
|
|
|
|
opts.OrderBy = db.SearchOrderBy("`badge`.id DESC")
|
|
newestFirst, count, err := user_model.SearchBadges(t.Context(), opts)
|
|
assert.NoError(t, err)
|
|
assert.EqualValues(t, 4, count)
|
|
assert.Equal(t, []string{"badge-sort-case", "badge-sort-a", "badge-sort-c", "badge-sort-b"}, collectBadgeSlugs(newestFirst))
|
|
|
|
opts.OrderBy = db.SearchOrderBy("`badge`.slug ASC")
|
|
alpha, count, err := user_model.SearchBadges(t.Context(), opts)
|
|
assert.NoError(t, err)
|
|
assert.EqualValues(t, 4, count)
|
|
assert.Equal(t, []string{"badge-sort-a", "badge-sort-b", "badge-sort-c", "badge-sort-case"}, collectBadgeSlugs(alpha))
|
|
|
|
opts.OrderBy = db.SearchOrderBy("`badge`.slug DESC")
|
|
reverseAlpha, count, err := user_model.SearchBadges(t.Context(), opts)
|
|
assert.NoError(t, err)
|
|
assert.EqualValues(t, 4, count)
|
|
assert.Equal(t, []string{"badge-sort-case", "badge-sort-c", "badge-sort-b", "badge-sort-a"}, collectBadgeSlugs(reverseAlpha))
|
|
|
|
opts.Keyword = "mixedcasekeyword"
|
|
opts.OrderBy = db.SearchOrderBy("`badge`.slug ASC")
|
|
caseInsensitive, count, err := user_model.SearchBadges(t.Context(), opts)
|
|
assert.NoError(t, err)
|
|
assert.EqualValues(t, 1, count)
|
|
assert.Equal(t, []string{"badge-sort-case"}, collectBadgeSlugs(caseInsensitive))
|
|
}
|
|
|
|
func collectBadgeSlugs(badges []*user_model.Badge) []string {
|
|
slugs := make([]string, 0, len(badges))
|
|
for _, badge := range badges {
|
|
slugs = append(slugs, badge.Slug)
|
|
}
|
|
return slugs
|
|
}
|