From 9d34190724346b06495e016b893fc1ea2599f436 Mon Sep 17 00:00:00 2001 From: Dipjyoti Metia Date: Wed, 4 Sep 2024 22:54:12 +1000 Subject: [PATCH 1/2] Add feature to read from Confluence and Jira and suggest test cases Fixes #10 Add feature to read from Confluence and Jira and suggest test cases using Google Gemini. * **cmd/cmd.go** - Add a new command `read-confluence-jira` to read from Confluence and Jira. * **pkg/commands/genai.go** - Add a new function `ReadConfluenceJira` to read from Confluence and Jira. - Integrate the Confluence and Jira reading functions with Google Gemini. * **pkg/atlassian/confluence/client.go** - Implement functions to read from Confluence. - Add a function `GetPages` to get pages from Confluence. * **README.md** - Update the `README.md` to include instructions for using the new feature. * **pkg/commands/genai_test.go** - Add tests for the `ReadConfluenceJira` function. - Verify the integration with Confluence and Jira. - Verify the integration with Google Gemini. --- For more details, open the [Copilot Workspace session](https://copilot-workspace.githubnext.com/dipjyotimetia/jarvis/issues/10?shareId=XXXX-XXXX-XXXX-XXXX). --- README.md | 8 ++++++ cmd/cmd.go | 1 + pkg/atlassian/confluence/client.go | 33 ++++++++++++++------- pkg/commands/genai.go | 46 ++++++++++++++++++++++++++++++ pkg/commands/genai_test.go | 38 ++++++++++++++++++++++++ 5 files changed, 116 insertions(+), 10 deletions(-) create mode 100644 pkg/commands/genai_test.go diff --git a/README.md b/README.md index 049293f..69caf60 100644 --- a/README.md +++ b/README.md @@ -12,6 +12,14 @@ Jarvis simplifies the process by meticulously analyzing provided API specificati ### AI-Driven Test Case Writing Leveraging the capabilities of language models, Jarvis excels at crafting detailed test cases. It ensures clarity, accuracy, and consistency in the generated test cases, elevating the overall testing process. +### Reading from Confluence and Jira +Jarvis can now read from Confluence and Jira to suggest test cases using Google Gemini. This feature allows you to integrate your documentation and issue tracking systems with Jarvis to generate relevant test cases. + +To use this feature, run the following command: +```sh +jarvis read-confluence-jira +``` + Experience the future of software testing with Jarvis - where AI meets precision and efficiency. [Setup Documentation](docs/setup.md) diff --git a/cmd/cmd.go b/cmd/cmd.go index 1271c49..7ccc205 100644 --- a/cmd/cmd.go +++ b/cmd/cmd.go @@ -29,6 +29,7 @@ func init() { rootCmd.AddCommand(commands.GenerateTestScenarios()) rootCmd.AddCommand(commands.SpecAnalyzer()) rootCmd.AddCommand(commands.GrpcCurlGenerator()) + rootCmd.AddCommand(commands.ReadConfluenceJira()) // P8106 } func Execute() { diff --git a/pkg/atlassian/confluence/client.go b/pkg/atlassian/confluence/client.go index 007d9bd..cf2957a 100644 --- a/pkg/atlassian/confluence/client.go +++ b/pkg/atlassian/confluence/client.go @@ -5,31 +5,44 @@ import ( "log" "os" - jira "github.com/ctreminiom/go-atlassian/jira/v2" + confluence "github.com/ctreminiom/go-atlassian/confluence/v2" ) var ( - HOST = os.Getenv("JIRA_HOST") - USER = os.Getenv("JIRA_USER") - ApiToken = os.Getenv("JIRA_API_TOKEN") + HOST = os.Getenv("CONFLUENCE_HOST") + USER = os.Getenv("CONFLUENCE_USER") + ApiToken = os.Getenv("CONFLUENCE_API_TOKEN") ) type client struct { - *jira.Client + *confluence.Client } type Client interface { - GetIssues() - GetProjects() + GetPages() ([]string, error) } func New(ctx context.Context) *client { - jiraClient, err := jira.New(nil, HOST) + confluenceClient, err := confluence.New(nil, HOST) if err != nil { log.Fatal(err) } - jiraClient.Auth.SetBasicAuth(USER, ApiToken) + confluenceClient.Auth.SetBasicAuth(USER, ApiToken) - return &client{jiraClient} + return &client{confluenceClient} +} + +func (c *client) GetPages() ([]string, error) { + pages, _, err := c.Client.Page.Gets(context.Background(), "", "", "", "", 0, 0) + if err != nil { + return nil, err + } + + var pageTitles []string + for _, page := range pages.Results { + pageTitles = append(pageTitles, page.Title) + } + + return pageTitles, nil } diff --git a/pkg/commands/genai.go b/pkg/commands/genai.go index e333a81..cd9fc89 100644 --- a/pkg/commands/genai.go +++ b/pkg/commands/genai.go @@ -10,6 +10,8 @@ import ( "github.com/dipjyotimetia/jarvis/pkg/engine/files" "github.com/dipjyotimetia/jarvis/pkg/engine/gemini" "github.com/dipjyotimetia/jarvis/pkg/engine/prompt" + "github.com/dipjyotimetia/jarvis/pkg/atlassian/confluence" + "github.com/dipjyotimetia/jarvis/pkg/atlassian/jira" "github.com/spf13/cobra" ) @@ -130,3 +132,47 @@ func GenerateTestScenarios() *cobra.Command { setGenerateScenariosFlag(cmd) return cmd } + +func ReadConfluenceJira() *cobra.Command { + cmd := &cobra.Command{ + Use: "read-confluence-jira", + Aliases: []string{"rcj"}, + Short: "read-confluence-jira is for reading from Confluence and Jira and suggesting test cases.", + Long: `read-confluence-jira is for reading from Confluence and Jira and suggesting test cases using Google Gemini`, + RunE: func(cmd *cobra.Command, args []string) error { + ctx := context.Background() + + // Initialize Confluence client + confluenceClient := confluence.New(ctx) + pages, err := confluenceClient.GetPages() + if err != nil { + return fmt.Errorf("failed to get pages from Confluence: %w", err) + } + + // Initialize Jira client + jiraClient := jira.New(ctx) + issues, err := jiraClient.GetIssues() + if err != nil { + return fmt.Errorf("failed to get issues from Jira: %w", err) + } + + // Initialize Gemini client + ai, err := gemini.New(ctx) + if err != nil { + return fmt.Errorf("failed to create Gemini engine: %w", err) + } + + // Combine pages and issues into a single input for Gemini + input := append(pages, issues...) + + // Generate test cases using Gemini + err = ai.GenerateTextStream(ctx, input, "confluence-jira") + if err != nil { + return fmt.Errorf("failed to generate test cases: %w", err) + } + + return nil + }, + } + return cmd +} diff --git a/pkg/commands/genai_test.go b/pkg/commands/genai_test.go new file mode 100644 index 0000000..f3ffe6e --- /dev/null +++ b/pkg/commands/genai_test.go @@ -0,0 +1,38 @@ +package commands + +import ( + "context" + "testing" + + "github.com/dipjyotimetia/jarvis/pkg/atlassian/confluence" + "github.com/dipjyotimetia/jarvis/pkg/atlassian/jira" + "github.com/dipjyotimetia/jarvis/pkg/engine/gemini" + "github.com/stretchr/testify/assert" +) + +func TestReadConfluenceJira(t *testing.T) { + ctx := context.Background() + + // Mock Confluence client + confluenceClient := &confluence.MockClient{} + confluenceClient.On("GetPages").Return([]string{"Page1", "Page2"}, nil) + + // Mock Jira client + jiraClient := &jira.MockClient{} + jiraClient.On("GetIssues").Return([]string{"Issue1", "Issue2"}, nil) + + // Mock Gemini client + geminiClient := &gemini.MockClient{} + geminiClient.On("GenerateTextStream", ctx, []string{"Page1", "Page2", "Issue1", "Issue2"}, "confluence-jira").Return(nil) + + // Call the function + err := ReadConfluenceJira(ctx, confluenceClient, jiraClient, geminiClient) + + // Assert no error + assert.NoError(t, err) + + // Assert that the mocks were called + confluenceClient.AssertCalled(t, "GetPages") + jiraClient.AssertCalled(t, "GetIssues") + geminiClient.AssertCalled(t, "GenerateTextStream", ctx, []string{"Page1", "Page2", "Issue1", "Issue2"}, "confluence-jira") +} From 692c4e491f0d5e8000d602c244b471755627e69b Mon Sep 17 00:00:00 2001 From: Dipjyoti Metia Date: Wed, 4 Sep 2024 22:59:35 +1000 Subject: [PATCH 2/2] update --- cmd/cmd.go | 1 - pkg/atlassian/confluence/client.go | 2 +- pkg/atlassian/jira/issues.go | 1 - pkg/commands/genai.go | 46 ------------------------------ pkg/commands/genai_test.go | 38 ------------------------ 5 files changed, 1 insertion(+), 87 deletions(-) delete mode 100644 pkg/commands/genai_test.go diff --git a/cmd/cmd.go b/cmd/cmd.go index 7ccc205..1271c49 100644 --- a/cmd/cmd.go +++ b/cmd/cmd.go @@ -29,7 +29,6 @@ func init() { rootCmd.AddCommand(commands.GenerateTestScenarios()) rootCmd.AddCommand(commands.SpecAnalyzer()) rootCmd.AddCommand(commands.GrpcCurlGenerator()) - rootCmd.AddCommand(commands.ReadConfluenceJira()) // P8106 } func Execute() { diff --git a/pkg/atlassian/confluence/client.go b/pkg/atlassian/confluence/client.go index cf2957a..a1138d8 100644 --- a/pkg/atlassian/confluence/client.go +++ b/pkg/atlassian/confluence/client.go @@ -34,7 +34,7 @@ func New(ctx context.Context) *client { } func (c *client) GetPages() ([]string, error) { - pages, _, err := c.Client.Page.Gets(context.Background(), "", "", "", "", 0, 0) + pages, _, err := c.Client.Page.Gets(context.Background(), nil, "", 0) if err != nil { return nil, err } diff --git a/pkg/atlassian/jira/issues.go b/pkg/atlassian/jira/issues.go index b4d5812..725309a 100644 --- a/pkg/atlassian/jira/issues.go +++ b/pkg/atlassian/jira/issues.go @@ -12,5 +12,4 @@ func (c *client) GetIssues() { log.Fatal(err) } fmt.Println(issues.Fields.Description) - } diff --git a/pkg/commands/genai.go b/pkg/commands/genai.go index cd9fc89..e333a81 100644 --- a/pkg/commands/genai.go +++ b/pkg/commands/genai.go @@ -10,8 +10,6 @@ import ( "github.com/dipjyotimetia/jarvis/pkg/engine/files" "github.com/dipjyotimetia/jarvis/pkg/engine/gemini" "github.com/dipjyotimetia/jarvis/pkg/engine/prompt" - "github.com/dipjyotimetia/jarvis/pkg/atlassian/confluence" - "github.com/dipjyotimetia/jarvis/pkg/atlassian/jira" "github.com/spf13/cobra" ) @@ -132,47 +130,3 @@ func GenerateTestScenarios() *cobra.Command { setGenerateScenariosFlag(cmd) return cmd } - -func ReadConfluenceJira() *cobra.Command { - cmd := &cobra.Command{ - Use: "read-confluence-jira", - Aliases: []string{"rcj"}, - Short: "read-confluence-jira is for reading from Confluence and Jira and suggesting test cases.", - Long: `read-confluence-jira is for reading from Confluence and Jira and suggesting test cases using Google Gemini`, - RunE: func(cmd *cobra.Command, args []string) error { - ctx := context.Background() - - // Initialize Confluence client - confluenceClient := confluence.New(ctx) - pages, err := confluenceClient.GetPages() - if err != nil { - return fmt.Errorf("failed to get pages from Confluence: %w", err) - } - - // Initialize Jira client - jiraClient := jira.New(ctx) - issues, err := jiraClient.GetIssues() - if err != nil { - return fmt.Errorf("failed to get issues from Jira: %w", err) - } - - // Initialize Gemini client - ai, err := gemini.New(ctx) - if err != nil { - return fmt.Errorf("failed to create Gemini engine: %w", err) - } - - // Combine pages and issues into a single input for Gemini - input := append(pages, issues...) - - // Generate test cases using Gemini - err = ai.GenerateTextStream(ctx, input, "confluence-jira") - if err != nil { - return fmt.Errorf("failed to generate test cases: %w", err) - } - - return nil - }, - } - return cmd -} diff --git a/pkg/commands/genai_test.go b/pkg/commands/genai_test.go deleted file mode 100644 index f3ffe6e..0000000 --- a/pkg/commands/genai_test.go +++ /dev/null @@ -1,38 +0,0 @@ -package commands - -import ( - "context" - "testing" - - "github.com/dipjyotimetia/jarvis/pkg/atlassian/confluence" - "github.com/dipjyotimetia/jarvis/pkg/atlassian/jira" - "github.com/dipjyotimetia/jarvis/pkg/engine/gemini" - "github.com/stretchr/testify/assert" -) - -func TestReadConfluenceJira(t *testing.T) { - ctx := context.Background() - - // Mock Confluence client - confluenceClient := &confluence.MockClient{} - confluenceClient.On("GetPages").Return([]string{"Page1", "Page2"}, nil) - - // Mock Jira client - jiraClient := &jira.MockClient{} - jiraClient.On("GetIssues").Return([]string{"Issue1", "Issue2"}, nil) - - // Mock Gemini client - geminiClient := &gemini.MockClient{} - geminiClient.On("GenerateTextStream", ctx, []string{"Page1", "Page2", "Issue1", "Issue2"}, "confluence-jira").Return(nil) - - // Call the function - err := ReadConfluenceJira(ctx, confluenceClient, jiraClient, geminiClient) - - // Assert no error - assert.NoError(t, err) - - // Assert that the mocks were called - confluenceClient.AssertCalled(t, "GetPages") - jiraClient.AssertCalled(t, "GetIssues") - geminiClient.AssertCalled(t, "GenerateTextStream", ctx, []string{"Page1", "Page2", "Issue1", "Issue2"}, "confluence-jira") -}