// Copyright 2021 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT package nuget import ( "archive/zip" "bytes" "maps" "slices" "testing" "github.com/stretchr/testify/assert" ) const ( authors = "Gitea Authors" copyright = "Package Copyright" dependencyID = "System.Text.Json" dependencyVersion = "5.0.0" developmentDependency = true description = "Package Description" iconURL = "https://gitea.io/favicon.png" id = "System.Gitea" language = "Package Language" licenseURL = "https://gitea.io/license" minClientVersion = "1.0.0.0" owners = "Package Owners" projectURL = "https://gitea.io" readme = "Readme" releaseNotes = "Package Release Notes" repositoryURL = "https://gitea.io/gitea/gitea" requireLicenseAcceptance = true tags = "tag_1 tag_2 tag_3" targetFramework = ".NETStandard2.1" title = "Package Title" versionStr = "1.0.1" ) const nuspecContent = ` ` + authors + ` ` + copyright + ` ` + description + ` true ` + iconURL + ` ` + id + ` ` + language + ` ` + licenseURL + ` ` + owners + ` ` + projectURL + ` README.md ` + releaseNotes + ` true ` + tags + ` ` + title + ` ` + versionStr + ` ` const symbolsNuspecContent = ` ` + id + ` ` + versionStr + ` ` + description + ` ` func TestParsePackageMetaData(t *testing.T) { createArchive := func(files map[string]string) []byte { var buf bytes.Buffer archive := zip.NewWriter(&buf) for _, name := range slices.Sorted(maps.Keys(files)) { w, _ := archive.Create(name) w.Write([]byte(files[name])) } archive.Close() return buf.Bytes() } for _, testCase := range []struct { name string files map[string]string expectedError error }{ {"MissingNuspecFile", map[string]string{"dummy.txt": ""}, ErrMissingNuspecFile}, {"MissingNuspecFileInRoot", map[string]string{"sub/package.nuspec": ""}, ErrMissingNuspecFile}, {"InvalidNuspecFile", map[string]string{"package.nuspec": ""}, nil}, {"InvalidPackageId", map[string]string{"package.nuspec": ` `}, ErrNuspecInvalidID}, {"InvalidPackageVersion", map[string]string{"package.nuspec": ` ` + id + ` `}, ErrNuspecInvalidVersion}, } { t.Run(testCase.name, func(t *testing.T) { data := createArchive(testCase.files) np, err := ParsePackageMetaData(bytes.NewReader(data), int64(len(data))) assert.Nil(t, np) if testCase.expectedError == nil { assert.Error(t, err) } else { assert.ErrorIs(t, err, testCase.expectedError) } }) } t.Run("MissingReadme", func(t *testing.T) { data := createArchive(map[string]string{"package.nuspec": nuspecContent}) np, err := ParsePackageMetaData(bytes.NewReader(data), int64(len(data))) assert.NoError(t, err) assert.NotNil(t, np) assert.Empty(t, np.Metadata.Readme) }) t.Run("IgnoresNuspecShadowingRootNuspec", func(t *testing.T) { data := createArchive(map[string]string{"/package.nuspec": "", "package.nuspec": nuspecContent}) np, err := ParsePackageMetaData(bytes.NewReader(data), int64(len(data))) assert.NoError(t, err) assert.Equal(t, id, np.ID) }) t.Run("Dependency Package", func(t *testing.T) { data := createArchive(map[string]string{ "package.nuspec": nuspecContent, "README.md": readme, }) np, err := ParsePackageMetaData(bytes.NewReader(data), int64(len(data))) assert.NoError(t, err) assert.NotNil(t, np) assert.Equal(t, DependencyPackage, np.PackageType) assert.Equal(t, authors, np.Metadata.Authors) assert.Equal(t, description, np.Metadata.Description) assert.Equal(t, id, np.ID) assert.Equal(t, versionStr, np.Version) assert.Equal(t, copyright, np.Metadata.Copyright) assert.Equal(t, developmentDependency, np.Metadata.DevelopmentDependency) assert.Equal(t, iconURL, np.Metadata.IconURL) assert.Equal(t, language, np.Metadata.Language) assert.Equal(t, licenseURL, np.Metadata.LicenseURL) assert.Equal(t, minClientVersion, np.Metadata.MinClientVersion) assert.Equal(t, owners, np.Metadata.Owners) assert.Equal(t, projectURL, np.Metadata.ProjectURL) assert.Equal(t, readme, np.Metadata.Readme) assert.Equal(t, releaseNotes, np.Metadata.ReleaseNotes) assert.Equal(t, repositoryURL, np.Metadata.RepositoryURL) assert.Equal(t, requireLicenseAcceptance, np.Metadata.RequireLicenseAcceptance) assert.Equal(t, tags, np.Metadata.Tags) assert.Equal(t, title, np.Metadata.Title) assert.Len(t, np.Metadata.Dependencies, 1) assert.Contains(t, np.Metadata.Dependencies, targetFramework) deps := np.Metadata.Dependencies[targetFramework] assert.Len(t, deps, 1) assert.Equal(t, dependencyID, deps[0].ID) assert.Equal(t, dependencyVersion, deps[0].Version) t.Run("NormalizedVersion", func(t *testing.T) { data := createArchive(map[string]string{"package.nuspec": ` test 1.04.5.2.5-rc.1+metadata `}) np, err := ParsePackageMetaData(bytes.NewReader(data), int64(len(data))) assert.NoError(t, err) assert.NotNil(t, np) assert.Equal(t, "1.4.5.2-rc.1", np.Version) }) }) t.Run("Symbols Package", func(t *testing.T) { data := createArchive(map[string]string{"package.nuspec": symbolsNuspecContent}) np, err := ParsePackageMetaData(bytes.NewReader(data), int64(len(data))) assert.NoError(t, err) assert.NotNil(t, np) assert.Equal(t, SymbolsPackage, np.PackageType) assert.Equal(t, id, np.ID) assert.Equal(t, versionStr, np.Version) assert.Equal(t, description, np.Metadata.Description) assert.Empty(t, np.Metadata.Dependencies) }) }