Skip to content
Draft
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
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,12 @@
# Ignore master key for decrypting credentials and more.
/config/master.key

# Coverage files
/coverage
coverage.out
coverage-integration.out
coverage-filtered.out
coverage-integration-filtered.out

# Ignore built binaries
/bin/
Expand Down
62 changes: 62 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,68 @@ ci-test-integration: install $(GOTESTSUM) ## Run integration tests with JSON out
.PHONY: test-all
test-all: lint test test-integration test-helm ## Run all checks (lint, unit, integration, helm)

.PHONY: test-coverage
test-coverage: ## Run unit tests with coverage (excludes generated code)
@echo "Running unit tests with coverage..."
@$(MAKE) test TESTFLAGS="-coverprofile=coverage.out -covermode=atomic -count=1"
@if [ -f coverage.out ]; then \
echo "Filtering out generated code (mocks, openapi) from coverage..."; \
grep -v -E '(_mock\.go|/mocks/|/openapi/)' coverage.out > coverage-filtered.out || true; \
mv coverage-filtered.out coverage.out; \
fi
@echo ""
@if [ -f coverage.out ]; then \
echo ""; \
echo "Coverage summary (excluding generated code):"; \
echo "Total Coverage: $$(go tool cover -func=coverage.out | tail -1 | awk '{print $$3}')"; \
echo ""; \
echo "To view detailed HTML coverage report, run: make coverage-html"; \
else \
echo "No coverage file generated."; \
fi

.PHONY: test-coverage-integration
test-coverage-integration: ## Run integration tests with coverage (excludes generated code)
@echo "Running integration tests with coverage..."
@$(MAKE) test-integration TESTFLAGS="-coverprofile=coverage-integration.out -covermode=atomic -coverpkg=./pkg/...,./cmd/... -count=1"
@if [ -f coverage-integration.out ]; then \
echo "Filtering out generated code (mocks, openapi) from coverage..."; \
grep -v -E '(_mock\.go|/mocks/|/openapi/)' coverage-integration.out > coverage-integration-filtered.out || true; \
mv coverage-integration-filtered.out coverage-integration.out; \
fi
@echo ""
@if [ -f coverage-integration.out ]; then \
echo ""; \
echo "Coverage summary (excluding generated code):"; \
echo "Total Coverage: $$(go tool cover -func=coverage-integration.out | tail -1 | awk '{print $$3}')"; \
echo ""; \
echo "To view detailed HTML coverage report, run: make coverage-integration-html"; \
fi

.PHONY: coverage-html
coverage-html: ## Open HTML coverage report for unit tests
@if [ ! -f coverage.out ]; then \
echo "No coverage.out file found. Run 'make test-coverage' first."; \
exit 1; \
fi
@echo "Opening coverage report in browser..."
@go tool cover -html=coverage.out

.PHONY: coverage-integration-html
coverage-integration-html: ## Open HTML coverage report for integration tests
@if [ ! -f coverage-integration.out ]; then \
echo "No coverage-integration.out file found. Run 'make test-coverage-integration' first."; \
exit 1; \
fi
@echo "Opening coverage report in browser..."
@go tool cover -html=coverage-integration.out

.PHONY: coverage-clean
coverage-clean: ## Remove all coverage files
@echo "Cleaning coverage files..."
@rm -f coverage.out coverage-integration.out coverage-unfiltered.out
@echo "Coverage files removed."

##@ Agent Verification

.PHONY: verify-all
Expand Down
70 changes: 70 additions & 0 deletions pkg/services/resource_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -843,6 +843,76 @@ func TestResourceService_Delete_CascadeSkipsAlreadyDeletedChild(t *testing.T) {
Expect(preDeletedExists).To(BeFalse())
}

// --- List ---

func TestResourceService_List_InjectsKindFilter(t *testing.T) {
RegisterTestingT(t)
setupTestDescriptors()

mockDao := newMockResourceDao()
svc, _, generic := newTestResourceService(mockDao)

args := &ListArguments{Page: 1, Size: 100}
_, _, svcErr := svc.List(context.Background(), "Channel", args)
Expect(svcErr).To(BeNil())
Expect(args.Search).To(Equal(""), "original args should not be mutated")
Expect(generic.listCalled).To(BeTrue())
Expect(generic.lastSearch).To(Equal("kind = 'Channel'"))
}

func TestResourceService_List_NilArgs(t *testing.T) {
RegisterTestingT(t)
setupTestDescriptors()

mockDao := newMockResourceDao()
svc, _, generic := newTestResourceService(mockDao)

_, _, svcErr := svc.List(context.Background(), "Version", nil)
Expect(svcErr).To(BeNil())
Expect(generic.listCalled).To(BeTrue())
Expect(generic.lastSearch).To(Equal("kind = 'Version'"))
}

func TestResourceService_List_AppendsToExistingSearch(t *testing.T) {
RegisterTestingT(t)
setupTestDescriptors()

mockDao := newMockResourceDao()
svc, _, generic := newTestResourceService(mockDao)

args := &ListArguments{Page: 1, Size: 100, Search: "name = 'stable'"}
_, _, svcErr := svc.List(context.Background(), "Channel", args)
Expect(svcErr).To(BeNil())
Expect(args.Search).To(Equal("name = 'stable'"), "original args should not be mutated")
Expect(generic.lastSearch).To(Equal("(name = 'stable') AND kind = 'Channel'"))
}

func TestResourceService_List_UnknownKind(t *testing.T) {
RegisterTestingT(t)
setupTestDescriptors()

mockDao := newMockResourceDao()
svc, _, _ := newTestResourceService(mockDao)

_, _, svcErr := svc.List(context.Background(), "UnknownKind", nil)
Expect(svcErr).ToNot(BeNil())
Expect(svcErr.Reason).To(ContainSubstring("Unknown entity kind"))
}

func TestResourceService_List_GenericServiceError(t *testing.T) {
RegisterTestingT(t)
setupTestDescriptors()

mockDao := newMockResourceDao()
svc, _, generic := newTestResourceService(mockDao)

generic.listErr = errors.GeneralError("database connection lost")

_, _, svcErr := svc.List(context.Background(), "Channel", nil)
Expect(svcErr).ToNot(BeNil())
Expect(svcErr.Reason).To(ContainSubstring("database connection lost"))
}

// --- GetByOwner ---

func TestResourceService_GetByOwner_HappyPath(t *testing.T) {
Expand Down
Loading