initial commit
This commit is contained in:
176
internal/application/specialist/service_test.go
Normal file
176
internal/application/specialist/service_test.go
Normal file
@@ -0,0 +1,176 @@
|
||||
package specialist_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"testing"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/rs/zerolog"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/mock"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
appMock "base/internal/application/mock"
|
||||
"base/internal/application/specialist"
|
||||
domainAsset "base/internal/domain/asset"
|
||||
domainProfile "base/internal/domain/profile"
|
||||
)
|
||||
|
||||
func TestSpecialistService_Overview(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
logger := zerolog.Nop()
|
||||
userID := uuid.New()
|
||||
profileID := uuid.New()
|
||||
|
||||
t.Run("success - returns overview with profile, assets, tasks", func(t *testing.T) {
|
||||
assetRepo := new(appMock.MockAssetRepository)
|
||||
profileRepo := new(appMock.MockProfileRepository)
|
||||
|
||||
profile := &domainProfile.Profile{
|
||||
ID: profileID,
|
||||
Handle: "specialist-user",
|
||||
UserID: &userID,
|
||||
Hero: domainProfile.Hero{
|
||||
FirstName: "Jane",
|
||||
LastName: "Doe",
|
||||
ShortDescription: "ML Engineer",
|
||||
},
|
||||
About: domainProfile.About{
|
||||
ProfilePicture: "avatar.jpg",
|
||||
About: "About me",
|
||||
},
|
||||
Skills: []domainProfile.Skill{
|
||||
{SkillName: "Go", Level: "expert"},
|
||||
},
|
||||
Contact: domainProfile.Contact{
|
||||
Email: "jane@example.com",
|
||||
SocialLinks: []domainProfile.SocialLink{{LinkType: "github", Link: "https://github.com/jane"}},
|
||||
},
|
||||
PageSetting: domainProfile.PageSetting{VisibilityLevel: "public"},
|
||||
}
|
||||
|
||||
asset := &domainAsset.Asset{
|
||||
ID: uuid.New(),
|
||||
ProfileID: profileID,
|
||||
Status: domainAsset.StatusPublished,
|
||||
AssetCategoryID: uuid.New(),
|
||||
Title: "My Project",
|
||||
Description: "A cool project",
|
||||
AssetArtifacts: []domainAsset.Artifact{{Type: "image", DownloadURL: "cover.png", Price: 0}},
|
||||
}
|
||||
|
||||
otherProfile := &domainProfile.Profile{
|
||||
ID: uuid.New(),
|
||||
Handle: "other-user",
|
||||
Hero: domainProfile.Hero{FirstName: "Other", LastName: "User"},
|
||||
PageSetting: domainProfile.PageSetting{VisibilityLevel: "public"},
|
||||
}
|
||||
|
||||
profileRepo.On("FindByUserID", ctx, userID).Return(profile, nil)
|
||||
assetRepo.On("FindByProfileID", ctx, profileID).Return([]*domainAsset.Asset{asset}, nil)
|
||||
profileRepo.On("FindAll", ctx, mock.MatchedBy(func(arg interface{}) bool {
|
||||
f, ok := arg.(domainProfile.Filter)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
return f.Page == 1 && f.PageSize == 6 && f.SortedBy == "created_at" && !f.Ascending
|
||||
})).Return([]*domainProfile.Profile{otherProfile}, 26, nil)
|
||||
assetRepo.On("Count", ctx).Return(42, nil)
|
||||
|
||||
svc := specialist.New(specialist.Param{
|
||||
Logger: logger,
|
||||
ProfileRepo: profileRepo,
|
||||
AssetRepo: assetRepo,
|
||||
})
|
||||
|
||||
resp, err := svc.Overview(ctx, userID)
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, resp)
|
||||
|
||||
assert.Equal(t, "", resp.Message)
|
||||
assert.Len(t, resp.Data.Assets, 1)
|
||||
assert.Equal(t, "My Project", resp.Data.Assets[0].Title)
|
||||
|
||||
assert.Len(t, resp.Data.RecentlyJoined, 1)
|
||||
assert.Equal(t, "other-user", resp.Data.RecentlyJoined[0].ProfileHandle)
|
||||
|
||||
assert.Equal(t, 42, resp.Data.Analytics.TotalAssets)
|
||||
assert.Equal(t, 26, resp.Data.Analytics.TotalProfiles)
|
||||
|
||||
require.NotNil(t, resp.Data.Profile)
|
||||
assert.Equal(t, "specialist-user", resp.Data.Profile.Handle)
|
||||
assert.Len(t, resp.Data.Skills, 1)
|
||||
assert.Equal(t, "Go", resp.Data.Skills[0].SkillName)
|
||||
|
||||
// All sections complete -> 100% or high completion
|
||||
assert.False(t, resp.Data.Tasks.ProfileAction)
|
||||
assert.False(t, resp.Data.Tasks.AboutAction)
|
||||
assert.False(t, resp.Data.Tasks.PublishAction)
|
||||
assert.False(t, resp.Data.Tasks.WorksAction)
|
||||
assert.False(t, resp.Data.Tasks.SkillsAction)
|
||||
assert.False(t, resp.Data.Tasks.SocialAction)
|
||||
assert.Equal(t, 100, resp.Data.CompletionPercent)
|
||||
|
||||
assetRepo.AssertExpectations(t)
|
||||
profileRepo.AssertExpectations(t)
|
||||
})
|
||||
|
||||
t.Run("profile not found returns ErrProfileNotFound", func(t *testing.T) {
|
||||
assetRepo := new(appMock.MockAssetRepository)
|
||||
profileRepo := new(appMock.MockProfileRepository)
|
||||
|
||||
profileRepo.On("FindByUserID", ctx, userID).Return(nil, domainProfile.ErrProfileNotFound)
|
||||
|
||||
svc := specialist.New(specialist.Param{
|
||||
Logger: logger,
|
||||
ProfileRepo: profileRepo,
|
||||
AssetRepo: assetRepo,
|
||||
})
|
||||
|
||||
resp, err := svc.Overview(ctx, userID)
|
||||
assert.Error(t, err)
|
||||
assert.True(t, errors.Is(err, domainProfile.ErrProfileNotFound))
|
||||
assert.Nil(t, resp)
|
||||
|
||||
profileRepo.AssertExpectations(t)
|
||||
})
|
||||
|
||||
t.Run("incomplete profile computes tasks and completion percent", func(t *testing.T) {
|
||||
assetRepo := new(appMock.MockAssetRepository)
|
||||
profileRepo := new(appMock.MockProfileRepository)
|
||||
|
||||
profile := &domainProfile.Profile{
|
||||
ID: profileID,
|
||||
Handle: "incomplete",
|
||||
UserID: &userID,
|
||||
Hero: domainProfile.Hero{FirstName: "A"}, // missing LastName, ShortDescription
|
||||
About: domainProfile.About{}, // missing picture, about
|
||||
Skills: []domainProfile.Skill{},
|
||||
PageSetting: domainProfile.PageSetting{VisibilityLevel: "private"},
|
||||
}
|
||||
|
||||
profileRepo.On("FindByUserID", ctx, userID).Return(profile, nil)
|
||||
assetRepo.On("FindByProfileID", ctx, profileID).Return([]*domainAsset.Asset{}, nil)
|
||||
profileRepo.On("FindAll", ctx, mock.Anything).Return([]*domainProfile.Profile{}, 0, nil)
|
||||
assetRepo.On("Count", ctx).Return(0, nil)
|
||||
|
||||
svc := specialist.New(specialist.Param{
|
||||
Logger: logger,
|
||||
ProfileRepo: profileRepo,
|
||||
AssetRepo: assetRepo,
|
||||
})
|
||||
|
||||
resp, err := svc.Overview(ctx, userID)
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, resp)
|
||||
|
||||
assert.True(t, resp.Data.Tasks.ProfileAction)
|
||||
assert.True(t, resp.Data.Tasks.AboutAction)
|
||||
assert.True(t, resp.Data.Tasks.PublishAction)
|
||||
assert.True(t, resp.Data.Tasks.WorksAction)
|
||||
assert.True(t, resp.Data.Tasks.SkillsAction)
|
||||
assert.True(t, resp.Data.Tasks.SocialAction)
|
||||
assert.Equal(t, 0, resp.Data.CompletionPercent)
|
||||
})
|
||||
}
|
||||
Reference in New Issue
Block a user