Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
89 changes: 89 additions & 0 deletions licensecheck/copyright_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (

"github.com/spf13/afero"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)

func TestHasMatchingCopyright(t *testing.T) {
Expand Down Expand Up @@ -273,3 +274,91 @@ func TestHasCopyright(t *testing.T) {
})
}
}

func TestHasMatchingCopyright_ErrorHandling(t *testing.T) {
t.Run("error on non-existent file", func(t *testing.T) {
hasCopyright, err := HasMatchingCopyright("/nonexistent/file.txt", "Copyright", false)
assert.NotNil(t, err)
assert.False(t, hasCopyright)
})
}

func TestHasMatchingCopyright_EdgeCases(t *testing.T) {
AppFs := afero.NewOsFs()
tempDir := t.TempDir()

t.Run("file exactly 300 bytes with copyright at end", func(t *testing.T) {
// Create a file exactly 300 bytes where "Copyright" appears at byte 290
padding := make([]byte, 290)
for i := range padding {
padding[i] = 'A'
}
content := string(padding) + "Copyright!"

f, err := afero.TempFile(AppFs, tempDir, "")
require.NoError(t, err)
err = afero.WriteFile(AppFs, f.Name(), []byte(content), 0644)
require.NoError(t, err)

hasCopyright, err := HasMatchingCopyright(f.Name(), "Copyright", false)
assert.Nil(t, err)
assert.True(t, hasCopyright)
})

t.Run("file less than 300 bytes", func(t *testing.T) {
content := "Short file with Copyright notice"

f, err := afero.TempFile(AppFs, tempDir, "")
require.NoError(t, err)
err = afero.WriteFile(AppFs, f.Name(), []byte(content), 0644)
require.NoError(t, err)

hasCopyright, err := HasMatchingCopyright(f.Name(), "Copyright", false)
assert.Nil(t, err)
assert.True(t, hasCopyright)
})

t.Run("file larger than 300 bytes with copyright after header", func(t *testing.T) {
// Create content > 300 bytes with copyright appearing after byte 300
header := make([]byte, 350)
for i := range header {
header[i] = 'X'
}
content := string(header) + "\nCopyright notice here"

f, _ := afero.TempFile(AppFs, tempDir, "")
_ = afero.WriteFile(AppFs, f.Name(), []byte(content), 0644)

// Should not find copyright since it's after the 300-byte header check
hasCopyright, err := HasMatchingCopyright(f.Name(), "Copyright", false)
assert.Nil(t, err)
assert.False(t, hasCopyright)
})

t.Run("empty search string", func(t *testing.T) {
f, _ := afero.TempFile(AppFs, tempDir, "")
_ = afero.WriteFile(AppFs, f.Name(), []byte("Some content"), 0644)

// Empty string should always be found
hasCopyright, err := HasMatchingCopyright(f.Name(), "", false)
assert.Nil(t, err)
assert.True(t, hasCopyright)
})

t.Run("search string longer than file", func(t *testing.T) {
f, _ := afero.TempFile(AppFs, tempDir, "")
_ = afero.WriteFile(AppFs, f.Name(), []byte("Short"), 0644)

hasCopyright, err := HasMatchingCopyright(f.Name(), "This is a very long copyright statement that is longer than the file content", false)
assert.Nil(t, err)
assert.False(t, hasCopyright)
})
}

func TestHasCopyright_ErrorHandling(t *testing.T) {
t.Run("error on non-existent file", func(t *testing.T) {
hasCopyright, err := HasCopyright("/nonexistent/file.txt")
assert.NotNil(t, err)
assert.False(t, hasCopyright)
})
}
158 changes: 154 additions & 4 deletions licensecheck/licensecheck_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,13 @@ package licensecheck
import (
"path/filepath"
"sort"
"strings"
"testing"

"github.com/samber/lo"
"github.com/spf13/afero"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)

func createTempFiles(t *testing.T, fileNames []string) (dirPath string, filePaths []string) {
Expand Down Expand Up @@ -85,14 +87,138 @@ func TestEnsureCorrectName(t *testing.T) {
}
}

func TestEnsureCorrectName_ErrorHandling(t *testing.T) {
t.Run("error when file does not exist", func(t *testing.T) {
_, err := EnsureCorrectName("/nonexistent/path/license.txt")
assert.NotNil(t, err)
})
}

func TestAddHeader(t *testing.T) {
// stub
t.Skip()
AppFs := afero.NewOsFs()

t.Run("add header to empty file", func(t *testing.T) {
tempDir := t.TempDir()
filePath := filepath.Join(tempDir, "test.txt")
_ = afero.WriteFile(AppFs, filePath, []byte(""), 0644)

header := "Copyright (c) 2023 Test Corp"
err := AddHeader(filePath, header)
assert.Nil(t, err)

// Read file and verify header was added
content, _ := afero.ReadFile(AppFs, filePath)
assert.Contains(t, string(content), header)
// Should have double newline after header
assert.Contains(t, string(content), header+"\n\n")
})

t.Run("add header to file with existing content", func(t *testing.T) {
tempDir := t.TempDir()
filePath := filepath.Join(tempDir, "test.txt")
originalContent := "This is the original file content"
err := afero.WriteFile(AppFs, filePath, []byte(originalContent), 0644)
require.NoError(t, err)

header := "Copyright (c) 2023 Test Corp"
err = AddHeader(filePath, header)
assert.Nil(t, err)

// Read file and verify header was prepended
content, _ := afero.ReadFile(AppFs, filePath)
assert.Contains(t, string(content), header)
assert.Contains(t, string(content), originalContent)
// Header should come before original content
headerIdx := strings.Index(string(content), header)
contentIdx := strings.Index(string(content), originalContent)
assert.Less(t, headerIdx, contentIdx)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Image

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey @mohanmanikanta2299, I changed header to just "C" in the "add header to file with existing content" sub-test and the test still passed. Please take a look and review the PR properly before sending it for review.

aatish@aatish-CLPJCQ9LWW copywrite % go test ./licensecheck/ -run "TestAddHeader/add_header_to_file_with_existing_content" -v -count=1
=== RUN   TestAddHeader
=== RUN   TestAddHeader/add_header_to_file_with_existing_content
--- PASS: TestAddHeader (0.00s)
    --- PASS: TestAddHeader/add_header_to_file_with_existing_content (0.00s)
PASS
ok      github.com/hashicorp/copywrite/licensecheck     0.971s

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mohanmanikanta2299 , please enable co-pilot review as well, it will help saving some time in review from other Devs.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed the concern.
Thanks

})

t.Run("add multi-line header", func(t *testing.T) {
tempDir := t.TempDir()
filePath := filepath.Join(tempDir, "test.txt")
_ = afero.WriteFile(AppFs, filePath, []byte("Original content"), 0644)

header := "Copyright (c) 2023 Test Corp\nSPDX-License-Identifier: MPL-2.0"
err := AddHeader(filePath, header)
assert.Nil(t, err)

content, _ := afero.ReadFile(AppFs, filePath)
assert.Contains(t, string(content), "Copyright (c) 2023 Test Corp")
assert.Contains(t, string(content), "SPDX-License-Identifier: MPL-2.0")
assert.Contains(t, string(content), "Original content")
})

t.Run("error on non-existent file", func(t *testing.T) {
header := "Copyright (c) 2023 Test Corp"
err := AddHeader("/nonexistent/path/file.txt", header)
assert.NotNil(t, err)
})
}

func TestAddLicenseFile(t *testing.T) {
// stub
t.Skip()
AppFs := afero.NewOsFs()

t.Run("create LICENSE file with MPL-2.0", func(t *testing.T) {
tempDir := t.TempDir()
licensePath, err := AddLicenseFile(tempDir, "MPL-2.0")
assert.Nil(t, err)
assert.NotEmpty(t, licensePath)

// Verify file exists
fileExists, _ := afero.Exists(AppFs, licensePath)
assert.True(t, fileExists)

// Verify content contains MPL-2.0 license text
content, _ := afero.ReadFile(AppFs, licensePath)
assert.Contains(t, string(content), "Mozilla Public License")
})

t.Run("create LICENSE file with Apache-2.0", func(t *testing.T) {
tempDir := t.TempDir()
licensePath, err := AddLicenseFile(tempDir, "Apache-2.0")
assert.Nil(t, err)

content, _ := afero.ReadFile(AppFs, licensePath)
assert.Contains(t, string(content), "Apache License")
})

t.Run("create LICENSE file with MIT", func(t *testing.T) {
tempDir := t.TempDir()
licensePath, err := AddLicenseFile(tempDir, "MIT")
assert.Nil(t, err)

content, _ := afero.ReadFile(AppFs, licensePath)
assert.Contains(t, string(content), "Permission is hereby granted")
})

t.Run("error on unknown SPDX ID", func(t *testing.T) {
tempDir := t.TempDir()
licensePath, err := AddLicenseFile(tempDir, "UNKNOWN-LICENSE-99")
assert.NotNil(t, err)
assert.Empty(t, licensePath)
assert.Contains(t, err.Error(), "unknown SPDX license ID")
})

t.Run("error on invalid directory path", func(t *testing.T) {
licensePath, err := AddLicenseFile("/nonexistent/invalid/path", "MPL-2.0")
assert.NotNil(t, err)
assert.Empty(t, licensePath)
})

t.Run("returned path is absolute", func(t *testing.T) {
tempDir := t.TempDir()
licensePath, err := AddLicenseFile(tempDir, "MPL-2.0")
assert.Nil(t, err)
assert.True(t, filepath.IsAbs(licensePath))
})

t.Run("file is named LICENSE", func(t *testing.T) {
tempDir := t.TempDir()
licensePath, err := AddLicenseFile(tempDir, "Apache-2.0")
assert.Nil(t, err)
assert.Equal(t, "LICENSE", filepath.Base(licensePath))
})
}

func sortSlice(input *[]string) {
Expand Down Expand Up @@ -179,3 +305,27 @@ func TestFindLicenseFiles(t *testing.T) {
})
}
}

func TestFindLicenseFiles_ErrorHandling(t *testing.T) {
t.Run("returns empty slice when directory doesn't exist", func(t *testing.T) {
// When the directory doesn't exist, glob returns empty without error
result, err := FindLicenseFiles("/nonexistent/directory/path")
assert.Nil(t, err)
assert.Equal(t, []string{}, result)
})

t.Run("handles subdirectories correctly", func(t *testing.T) {
AppFs := afero.NewOsFs()
tempDir := t.TempDir()

// Create a subdirectory with a LICENSE file
subDir := filepath.Join(tempDir, "subdir")
_ = AppFs.MkdirAll(subDir, 0755)
_ = afero.WriteFile(AppFs, filepath.Join(subDir, "LICENSE"), []byte("sublicense"), 0644)

// FindLicenseFiles should only find files in the top-level directory, not subdirs
result, err := FindLicenseFiles(tempDir)
assert.Nil(t, err)
assert.Equal(t, []string{}, result)
})
}
Loading
Loading