issuer 0.1.0 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.adoc +1 -1
- data/issuer.gemspec +5 -9
- data/lib/issuer/cli.rb +5 -5
- data/lib/issuer/issue.rb +26 -13
- data/lib/issuer/sites/base.rb +2 -1
- data/lib/issuer/sites/github.rb +29 -4
- metadata +2 -36
- data/.rspec +0 -3
- data/.vale/config/vocabularies/issuer/accept.txt +0 -63
- data/.vale/config/vocabularies/issuer/reject.txt +0 -21
- data/.vale.ini +0 -42
- data/Dockerfile +0 -43
- data/Rakefile +0 -70
- data/bin/console +0 -0
- data/bin/issuer +0 -13
- data/bin/setup +0 -0
- data/examples/README.adoc +0 -56
- data/scripts/build.sh +0 -40
- data/scripts/lint-docs.sh +0 -64
- data/scripts/manage-runs.rb +0 -175
- data/scripts/pre-commit-template.sh +0 -54
- data/scripts/publish.sh +0 -92
- data/scripts/setup-vale.sh +0 -59
- data/specs/tests/README.adoc +0 -451
- data/specs/tests/check-github-connectivity.sh +0 -130
- data/specs/tests/cleanup-github-tests.sh +0 -374
- data/specs/tests/github-api/01-auth-connection.yml +0 -21
- data/specs/tests/github-api/02-basic-issues.yml +0 -90
- data/specs/tests/github-api/03-milestone-tests.yml +0 -58
- data/specs/tests/github-api/04-label-tests.yml +0 -98
- data/specs/tests/github-api/05-assignment-tests.yml +0 -55
- data/specs/tests/github-api/06-automation-tests.yml +0 -102
- data/specs/tests/github-api/07-error-tests.yml +0 -29
- data/specs/tests/github-api/08-complex-tests.yml +0 -197
- data/specs/tests/github-api/config.yml.example +0 -17
- data/specs/tests/rspec/cli_spec.rb +0 -127
- data/specs/tests/rspec/issue_spec.rb +0 -184
- data/specs/tests/rspec/issuer_spec.rb +0 -5
- data/specs/tests/rspec/ops_spec.rb +0 -124
- data/specs/tests/rspec/spec_helper.rb +0 -54
- data/specs/tests/run-github-api-tests.sh +0 -424
@@ -1,102 +0,0 @@
|
|
1
|
-
$meta:
|
2
|
-
proj: DocOps/issuer-test # Test repository # Update this with your test repository
|
3
|
-
|
4
|
-
issues:
|
5
|
-
- summ: "[TEST] Auto-metadata flag test"
|
6
|
-
body: |
|
7
|
-
# Automation Flag Test
|
8
|
-
|
9
|
-
This issue tests the `--auto-metadata` flag functionality.
|
10
|
-
|
11
|
-
**What this tests:**
|
12
|
-
- Automatic milestone creation without user prompts
|
13
|
-
- Automatic label creation without user prompts
|
14
|
-
- Combined automation of both milestones and labels
|
15
|
-
|
16
|
-
**Expected behavior when run with `--auto-metadata`:**
|
17
|
-
1. A new milestone "auto-test-milestone-v1.0" should be created automatically
|
18
|
-
2. New labels should be created automatically without prompts
|
19
|
-
3. No interactive confirmations should appear
|
20
|
-
4. The issue should be created with all metadata properly assigned
|
21
|
-
|
22
|
-
**Test commands:**
|
23
|
-
```bash
|
24
|
-
# This should prompt for milestone/label creation
|
25
|
-
issuer 06-automation-tests.yml
|
26
|
-
|
27
|
-
# This should create everything automatically without prompts
|
28
|
-
issuer 06-automation-tests.yml --auto-metadata
|
29
|
-
|
30
|
-
# Individual automation flags
|
31
|
-
issuer 06-automation-tests.yml --auto-versions --auto-tags
|
32
|
-
issuer 06-automation-tests.yml --auto-milestones --auto-labels
|
33
|
-
```
|
34
|
-
|
35
|
-
**Expected milestones/labels created:**
|
36
|
-
- Milestone: auto-test-milestone-v1.0
|
37
|
-
- Labels: auto-test-label-1, auto-test-label-2
|
38
|
-
vrsn: auto-test-milestone-v1.0
|
39
|
-
tags: [auto-test-label-1, auto-test-label-2]
|
40
|
-
|
41
|
-
- summ: "[TEST] Individual automation flags test"
|
42
|
-
body: |
|
43
|
-
# Individual Automation Flags Test
|
44
|
-
|
45
|
-
This issue tests the individual automation flags:
|
46
|
-
- `--auto-versions` / `--auto-milestones`
|
47
|
-
- `--auto-tags` / `--auto-labels`
|
48
|
-
|
49
|
-
**Test scenarios:**
|
50
|
-
|
51
|
-
1. **Only milestone automation:**
|
52
|
-
```bash
|
53
|
-
issuer 06-automation-tests.yml --auto-versions
|
54
|
-
```
|
55
|
-
Should create milestone automatically but prompt for labels.
|
56
|
-
|
57
|
-
2. **Only label automation:**
|
58
|
-
```bash
|
59
|
-
issuer 06-automation-tests.yml --auto-tags
|
60
|
-
```
|
61
|
-
Should create labels automatically but prompt for milestone.
|
62
|
-
|
63
|
-
3. **Both flags together:**
|
64
|
-
```bash
|
65
|
-
issuer 06-automation-tests.yml --auto-versions --auto-tags
|
66
|
-
```
|
67
|
-
Should work the same as `--auto-metadata`.
|
68
|
-
|
69
|
-
**Expected resources:**
|
70
|
-
- Milestone: individual-test-milestone-v2.0
|
71
|
-
- Labels: individual-test-label-1, individual-test-label-2
|
72
|
-
vrsn: individual-test-milestone-v2.0
|
73
|
-
tags: [individual-test-label-1, individual-test-label-2]
|
74
|
-
|
75
|
-
- summ: "[TEST] Alias flag compatibility test"
|
76
|
-
body: |
|
77
|
-
# Alias Flag Compatibility Test
|
78
|
-
|
79
|
-
This issue tests that the alias flags work correctly:
|
80
|
-
|
81
|
-
**Milestone aliases:**
|
82
|
-
- `--auto-versions` (primary)
|
83
|
-
- `--auto-milestones` (alias)
|
84
|
-
|
85
|
-
**Label aliases:**
|
86
|
-
- `--auto-tags` (primary)
|
87
|
-
- `--auto-labels` (alias)
|
88
|
-
|
89
|
-
**Test commands that should work identically:**
|
90
|
-
```bash
|
91
|
-
issuer 06-automation-tests.yml --auto-versions --auto-tags
|
92
|
-
issuer 06-automation-tests.yml --auto-milestones --auto-labels
|
93
|
-
issuer 06-automation-tests.yml --auto-metadata
|
94
|
-
```
|
95
|
-
|
96
|
-
All three commands should produce the same result with no user prompts.
|
97
|
-
|
98
|
-
**Expected resources:**
|
99
|
-
- Milestone: alias-test-milestone-v3.0
|
100
|
-
- Labels: alias-test-label-1, alias-test-label-2
|
101
|
-
vrsn: alias-test-milestone-v3.0
|
102
|
-
tags: [alias-test-label-1, alias-test-label-2]
|
@@ -1,29 +0,0 @@
|
|
1
|
-
$meta:
|
2
|
-
proj: nonexistent/repository # This should fail - testing error handling
|
3
|
-
|
4
|
-
issues:
|
5
|
-
- summ: "[TEST] This should fail gracefully"
|
6
|
-
body: |
|
7
|
-
# Error Handling Test
|
8
|
-
|
9
|
-
This issue should **NOT** be created successfully because the repository doesn't exist.
|
10
|
-
|
11
|
-
**What this tests:**
|
12
|
-
- Error handling for invalid repository names
|
13
|
-
- Graceful failure with informative error messages
|
14
|
-
- No crashes or unexpected behavior
|
15
|
-
|
16
|
-
**Expected behavior:**
|
17
|
-
- The CLI should detect that the repository doesn't exist
|
18
|
-
- A clear error message should be displayed
|
19
|
-
- The program should exit gracefully without creating any issues
|
20
|
-
- No partial state should be left behind
|
21
|
-
|
22
|
-
**Test commands:**
|
23
|
-
```bash
|
24
|
-
# This should fail with a clear error message
|
25
|
-
issuer 07-error-tests.yml --dry # Should fail even in dry-run
|
26
|
-
issuer 07-error-tests.yml # Should fail with repository error
|
27
|
-
```
|
28
|
-
|
29
|
-
If you're seeing this issue in GitHub, something went wrong with the test!
|
@@ -1,197 +0,0 @@
|
|
1
|
-
$meta:
|
2
|
-
proj: DocOps/issuer-test # Test repository # Update this with your test repository
|
3
|
-
defaults:
|
4
|
-
vrsn: complex-test-v1.0
|
5
|
-
user: briandominick # GitHub username # Update this with your GitHub username
|
6
|
-
tags: [+comprehensive-test, test-suite]
|
7
|
-
stub: true
|
8
|
-
head: |
|
9
|
-
## 🧪 Comprehensive Test Issue
|
10
|
-
This issue tests multiple features simultaneously.
|
11
|
-
|
12
|
-
**Test run timestamp:** $(date)
|
13
|
-
**Test type:** Complex integration test
|
14
|
-
|
15
|
-
---
|
16
|
-
tail: |
|
17
|
-
---
|
18
|
-
|
19
|
-
**Generated by:** issuer comprehensive test suite
|
20
|
-
**Features tested:** Multiple milestones, labels, assignments, stubs, markdown
|
21
|
-
**Cleanup:** This issue can be closed after test verification
|
22
|
-
body: |
|
23
|
-
Default body for comprehensive testing scenario.
|
24
|
-
|
25
|
-
This text should appear in issues that don't override the body,
|
26
|
-
surrounded by the head and tail content above and below.
|
27
|
-
|
28
|
-
issues:
|
29
|
-
- summ: "[TEST] Everything combined - kitchen sink test"
|
30
|
-
body: |
|
31
|
-
# Kitchen Sink Integration Test 🚀
|
32
|
-
|
33
|
-
This issue tests the maximum number of features in a single issue:
|
34
|
-
|
35
|
-
## Features Being Tested
|
36
|
-
|
37
|
-
### ✅ Issue Creation
|
38
|
-
- [x] Custom title and body
|
39
|
-
- [x] Markdown formatting
|
40
|
-
- [x] Complex content structure
|
41
|
-
|
42
|
-
### ✅ Milestone Management
|
43
|
-
- [x] Custom milestone (different from default)
|
44
|
-
- [x] Milestone creation if not exists
|
45
|
-
|
46
|
-
### ✅ Label Management
|
47
|
-
- [x] Multiple custom labels
|
48
|
-
- [x] Mix of new and potentially existing labels
|
49
|
-
- [x] Label creation if not exists
|
50
|
-
|
51
|
-
### ✅ Assignment
|
52
|
-
- [x] Issue assignment to specific user
|
53
|
-
|
54
|
-
### ✅ Content Features
|
55
|
-
- [x] Headers and subheaders
|
56
|
-
- [x] Lists and checkboxes
|
57
|
-
- [x] **Bold** and *italic* text
|
58
|
-
- [x] `inline code`
|
59
|
-
- [x] Code blocks
|
60
|
-
- [x] Tables
|
61
|
-
- [x] Links
|
62
|
-
- [x] Emojis 🎯 📊 ⚡
|
63
|
-
|
64
|
-
## Code Examples
|
65
|
-
|
66
|
-
```yaml
|
67
|
-
# IMYML example
|
68
|
-
$meta:
|
69
|
-
proj: user/repo
|
70
|
-
defaults:
|
71
|
-
vrsn: v1.0.0
|
72
|
-
tags: [enhancement]
|
73
|
-
|
74
|
-
issues:
|
75
|
-
- summ: Complex issue
|
76
|
-
body: Advanced content
|
77
|
-
vrsn: v1.1.0
|
78
|
-
tags: [feature, testing]
|
79
|
-
user: developer
|
80
|
-
```
|
81
|
-
|
82
|
-
```javascript
|
83
|
-
// JavaScript example
|
84
|
-
function createIssue(data) {
|
85
|
-
return fetch('/api/issues', {
|
86
|
-
method: 'POST',
|
87
|
-
body: JSON.stringify(data),
|
88
|
-
headers: { 'Content-Type': 'application/json' }
|
89
|
-
});
|
90
|
-
}
|
91
|
-
```
|
92
|
-
|
93
|
-
## Data Table
|
94
|
-
|
95
|
-
| Component | Status | Notes |
|
96
|
-
|-----------|---------|-------|
|
97
|
-
| Authentication | ✅ | Working |
|
98
|
-
| Issue Creation | ✅ | Working |
|
99
|
-
| Milestone Creation | ✅ | Working |
|
100
|
-
| Label Creation | ✅ | Working |
|
101
|
-
| Assignment | ✅ | Working |
|
102
|
-
| Markdown Support | ✅ | Working |
|
103
|
-
| Error Handling | 🧪 | Testing |
|
104
|
-
|
105
|
-
## External References
|
106
|
-
|
107
|
-
- [GitHub Issues API](https://docs.github.com/en/rest/issues)
|
108
|
-
- [issuer CLI Documentation](https://github.com/DocOps/issuer)
|
109
|
-
- [IMYML Format Specification](https://github.com/DocOps/issuer#imyml-format)
|
110
|
-
|
111
|
-
## Completion Criteria
|
112
|
-
|
113
|
-
This test is successful if:
|
114
|
-
|
115
|
-
1. ✅ This issue is created without errors
|
116
|
-
2. ✅ The milestone "complex-test-v1.1" is created
|
117
|
-
3. ✅ All specified labels are created and applied
|
118
|
-
4. ✅ The issue is assigned to the specified user
|
119
|
-
5. ✅ All markdown formatting renders correctly
|
120
|
-
6. ✅ No errors occur during the creation process
|
121
|
-
|
122
|
-
> **Important:** This is a test issue and can be closed after verification.
|
123
|
-
|
124
|
-
vrsn: complex-test-v1.1
|
125
|
-
tags: [enhancement, test-complex, high-priority, integration-test]
|
126
|
-
user: briandominick # GitHub username # Update this with your GitHub username
|
127
|
-
|
128
|
-
- summ: "[TEST] Stub functionality with defaults"
|
129
|
-
# This issue should use the default body with head/tail from metadata
|
130
|
-
vrsn: complex-test-v1.0
|
131
|
-
tags: [test-stub, automation]
|
132
|
-
|
133
|
-
- summ: "[TEST] Mixed content and overrides"
|
134
|
-
body: |
|
135
|
-
# Override Test
|
136
|
-
|
137
|
-
This issue tests overriding defaults while keeping some:
|
138
|
-
|
139
|
-
- ✅ Custom body (overrides default)
|
140
|
-
- ✅ Custom milestone (overrides default)
|
141
|
-
- ✅ Custom labels (combined with defaults)
|
142
|
-
- ✅ Custom user (overrides default)
|
143
|
-
|
144
|
-
**Expected behavior:**
|
145
|
-
- Should NOT use the default body/head/tail (because custom body provided)
|
146
|
-
- Should use custom milestone instead of default
|
147
|
-
- Should combine custom labels with default labels
|
148
|
-
- Should be assigned to the custom user
|
149
|
-
|
150
|
-
This tests the precedence rules in the IMYML processing.
|
151
|
-
vrsn: complex-test-override
|
152
|
-
tags: [test-override, custom-behavior]
|
153
|
-
user: briandominick # GitHub username # Update this with your GitHub username
|
154
|
-
|
155
|
-
- summ: "[TEST] Edge case - very long title with special characters and unicode 🌟 αβγδε ñáéíóú 中文"
|
156
|
-
body: |
|
157
|
-
# Edge Case Testing 🎯
|
158
|
-
|
159
|
-
This issue tests edge cases and boundary conditions:
|
160
|
-
|
161
|
-
## Long Title Testing
|
162
|
-
The title of this issue is intentionally long and contains:
|
163
|
-
- Special characters
|
164
|
-
- Unicode characters
|
165
|
-
- Emojis
|
166
|
-
- Mixed languages
|
167
|
-
|
168
|
-
## Large Content Testing
|
169
|
-
This body contains a substantial amount of content to test handling of larger payloads.
|
170
|
-
|
171
|
-
### Lorem Ipsum Content
|
172
|
-
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
|
173
|
-
|
174
|
-
Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt.
|
175
|
-
|
176
|
-
### Technical Content
|
177
|
-
```json
|
178
|
-
{
|
179
|
-
"test": {
|
180
|
-
"edge_cases": true,
|
181
|
-
"unicode_support": "🌟 αβγδε ñáéíóú 中文 العربية",
|
182
|
-
"special_chars": "!@#$%^&*()_+-=[]{}|;':\",./<>?",
|
183
|
-
"long_strings": "This is a very long string that tests the handling of substantial content in issue bodies and ensures that the GitHub API can handle larger payloads without truncation or encoding issues.",
|
184
|
-
"nested_data": {
|
185
|
-
"level_1": {
|
186
|
-
"level_2": {
|
187
|
-
"level_3": "Deep nesting test"
|
188
|
-
}
|
189
|
-
}
|
190
|
-
}
|
191
|
-
}
|
192
|
-
}
|
193
|
-
```
|
194
|
-
|
195
|
-
This issue should be created successfully despite its complex content.
|
196
|
-
vrsn: complex-test-edge-cases
|
197
|
-
tags: [test-edge-cases, unicode-test, large-content]
|
@@ -1,17 +0,0 @@
|
|
1
|
-
# GitHub API Test Configuration
|
2
|
-
# Copy this file to config.yml and customize for your test repository
|
3
|
-
|
4
|
-
# Test repository configuration
|
5
|
-
test_repo: "your-username/issuer-test-repo" # Replace with your test repository
|
6
|
-
test_username: "your-username" # Replace with your GitHub username
|
7
|
-
|
8
|
-
# Test configuration
|
9
|
-
cleanup_after_tests: true # Whether to clean up test issues after running
|
10
|
-
max_test_issues: 50 # Maximum number of test issues to create
|
11
|
-
test_label_prefix: "test-" # Prefix for test labels
|
12
|
-
test_milestone_prefix: "test-milestone-" # Prefix for test milestones
|
13
|
-
|
14
|
-
# Advanced options
|
15
|
-
dry_run_first: true # Always do a dry run before actual posting
|
16
|
-
create_cleanup_script: true # Generate cleanup script after tests
|
17
|
-
verbose_output: true # Show detailed output during tests
|
@@ -1,127 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require_relative "spec_helper"
|
4
|
-
|
5
|
-
RSpec.describe Issuer::CLI do
|
6
|
-
# Mock the GitHub site methods to avoid actual API calls during testing
|
7
|
-
before do
|
8
|
-
allow_any_instance_of(Issuer::Sites::GitHub).to receive(:get_versions).and_return([])
|
9
|
-
allow_any_instance_of(Issuer::Sites::GitHub).to receive(:find_milestone).and_return(nil)
|
10
|
-
allow_any_instance_of(Issuer::Sites::GitHub).to receive(:convert_issue_to_site_params).and_wrap_original do |method, *args|
|
11
|
-
issue, repo = args
|
12
|
-
{
|
13
|
-
title: issue.summ,
|
14
|
-
body: issue.body,
|
15
|
-
labels: issue.tags || [],
|
16
|
-
assignee: issue.user,
|
17
|
-
milestone: issue.vrsn
|
18
|
-
}
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
|
-
describe 'file argument handling' do
|
23
|
-
let(:sample_file) { create_temp_yaml_file(sample_imyml_content) }
|
24
|
-
|
25
|
-
after { File.unlink(sample_file) if File.exist?(sample_file) }
|
26
|
-
|
27
|
-
it 'accepts positional file argument' do
|
28
|
-
# Capture output to avoid cluttering test output
|
29
|
-
expect {
|
30
|
-
cli = Issuer::CLI.new
|
31
|
-
cli.invoke(:main, [sample_file], {dry: true})
|
32
|
-
}.to output(/Would process 2 issues/).to_stdout
|
33
|
-
end
|
34
|
-
|
35
|
-
it 'accepts --file option' do
|
36
|
-
expect {
|
37
|
-
cli = Issuer::CLI.new
|
38
|
-
cli.invoke(:main, [], {file: sample_file, dry: true})
|
39
|
-
}.to output(/Would process 2 issues/).to_stdout
|
40
|
-
end
|
41
|
-
|
42
|
-
it 'gives precedence to --file over positional argument' do
|
43
|
-
nonexistent_file = '/tmp/nonexistent.yml'
|
44
|
-
|
45
|
-
expect {
|
46
|
-
cli = Issuer::CLI.new
|
47
|
-
cli.invoke(:main, [nonexistent_file], {file: sample_file, dry: true})
|
48
|
-
}.to output(/Would process 2 issues/).to_stdout
|
49
|
-
end
|
50
|
-
|
51
|
-
it 'shows error when no file is specified' do
|
52
|
-
expect {
|
53
|
-
cli = Issuer::CLI.new
|
54
|
-
cli.invoke(:main, [], {})
|
55
|
-
}.to raise_error(SystemExit).and output(/No IMYML file specified/).to_stderr
|
56
|
-
end
|
57
|
-
|
58
|
-
it 'shows error when file does not exist' do
|
59
|
-
expect {
|
60
|
-
cli = Issuer::CLI.new
|
61
|
-
cli.invoke(:main, ['/tmp/nonexistent.yml'], {})
|
62
|
-
}.to raise_error(SystemExit).and output(/File not found/).to_stderr
|
63
|
-
end
|
64
|
-
end
|
65
|
-
|
66
|
-
describe 'option handling' do
|
67
|
-
let(:sample_file) { create_temp_yaml_file(sample_imyml_content) }
|
68
|
-
|
69
|
-
after { File.unlink(sample_file) if File.exist?(sample_file) }
|
70
|
-
|
71
|
-
it 'handles --proj option' do
|
72
|
-
expect {
|
73
|
-
cli = Issuer::CLI.new
|
74
|
-
cli.invoke(:main, [sample_file], {proj: 'custom/repo', dry: true})
|
75
|
-
}.to output(/repo:\s+custom\/repo/).to_stdout
|
76
|
-
end
|
77
|
-
|
78
|
-
it 'handles --tags option with append and default logic' do
|
79
|
-
expect {
|
80
|
-
cli = Issuer::CLI.new
|
81
|
-
cli.invoke(:main, [sample_file], {tags: '+urgent,docs', dry: true})
|
82
|
-
}.to output(/- urgent/).to_stdout
|
83
|
-
end
|
84
|
-
|
85
|
-
it 'handles --stub option' do
|
86
|
-
expect {
|
87
|
-
cli = Issuer::CLI.new
|
88
|
-
cli.invoke(:main, [sample_file], {stub: true, dry: true})
|
89
|
-
}.to output(/Would process 2 issues/).to_stdout
|
90
|
-
end
|
91
|
-
|
92
|
-
it 'handles --tokenv option' do
|
93
|
-
ENV['MY_GITHUB_TOKEN'] = 'ghp_xxxxx'
|
94
|
-
|
95
|
-
# Mock the Factory to capture the site_options passed to it
|
96
|
-
allow(Issuer::Sites::Factory).to receive(:create).and_call_original
|
97
|
-
|
98
|
-
cli = Issuer::CLI.new
|
99
|
-
cli.invoke(:main, [sample_file], {tokenv: 'MY_GITHUB_TOKEN', dry: true})
|
100
|
-
|
101
|
-
# Verify that Factory.create was called with the correct token_env_var
|
102
|
-
expect(Issuer::Sites::Factory).to have_received(:create).with(
|
103
|
-
'github',
|
104
|
-
hash_including(token_env_var: 'MY_GITHUB_TOKEN')
|
105
|
-
)
|
106
|
-
|
107
|
-
ENV.delete('MY_GITHUB_TOKEN')
|
108
|
-
end
|
109
|
-
|
110
|
-
end
|
111
|
-
|
112
|
-
describe 'version and help' do
|
113
|
-
it 'shows version with --version' do
|
114
|
-
expect {
|
115
|
-
cli = Issuer::CLI.new
|
116
|
-
cli.invoke(:main, [], {version: true})
|
117
|
-
}.to output(/Issuer version/).to_stdout
|
118
|
-
end
|
119
|
-
|
120
|
-
it 'shows help with --help' do
|
121
|
-
expect {
|
122
|
-
cli = Issuer::CLI.new
|
123
|
-
cli.invoke(:main, [], {help: true})
|
124
|
-
}.to output(/Usage:/).to_stdout
|
125
|
-
end
|
126
|
-
end
|
127
|
-
end
|
@@ -1,184 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require_relative "spec_helper"
|
4
|
-
|
5
|
-
RSpec.describe Issuer::Issue do
|
6
|
-
let(:issue_data) do
|
7
|
-
{
|
8
|
-
'summ' => 'Test issue title',
|
9
|
-
'desc' => 'Test issue description',
|
10
|
-
'tags' => ['bug', 'high-priority'],
|
11
|
-
'user' => 'testuser',
|
12
|
-
'vrsn' => '1.0.0'
|
13
|
-
}
|
14
|
-
end
|
15
|
-
|
16
|
-
let(:defaults) do
|
17
|
-
{
|
18
|
-
'user' => 'defaultuser',
|
19
|
-
'tags' => ['default-tag']
|
20
|
-
}
|
21
|
-
end
|
22
|
-
|
23
|
-
describe '#initialize' do
|
24
|
-
it 'initializes with issue data and defaults' do
|
25
|
-
issue = described_class.new(issue_data, defaults)
|
26
|
-
|
27
|
-
expect(issue.summ).to eq('Test issue title')
|
28
|
-
expect(issue.body).to eq('Test issue description')
|
29
|
-
expect(issue.tags).to eq(['bug', 'high-priority'])
|
30
|
-
expect(issue.user).to eq('testuser')
|
31
|
-
expect(issue.vrsn).to eq('1.0.0')
|
32
|
-
end
|
33
|
-
|
34
|
-
it 'merges defaults with issue data, preferring issue data' do
|
35
|
-
issue = described_class.new(issue_data, defaults)
|
36
|
-
|
37
|
-
# Issue data should override defaults
|
38
|
-
expect(issue.user).to eq('testuser')
|
39
|
-
expect(issue.tags).to eq(['bug', 'high-priority'])
|
40
|
-
end
|
41
|
-
|
42
|
-
it 'uses defaults when issue data is missing fields' do
|
43
|
-
minimal_data = { 'summ' => 'Title only' }
|
44
|
-
issue = described_class.new(minimal_data, defaults)
|
45
|
-
|
46
|
-
expect(issue.summ).to eq('Title only')
|
47
|
-
expect(issue.user).to eq('defaultuser')
|
48
|
-
expect(issue.tags).to eq(['default-tag'])
|
49
|
-
end
|
50
|
-
end
|
51
|
-
|
52
|
-
describe '#valid?' do
|
53
|
-
it 'returns true for issues with a title' do
|
54
|
-
issue = described_class.new(issue_data)
|
55
|
-
expect(issue).to be_valid
|
56
|
-
end
|
57
|
-
|
58
|
-
it 'returns false for issues without a title' do
|
59
|
-
invalid_data = { 'desc' => 'Description only' }
|
60
|
-
issue = described_class.new(invalid_data)
|
61
|
-
expect(issue).not_to be_valid
|
62
|
-
end
|
63
|
-
|
64
|
-
it 'returns false for issues with empty title' do
|
65
|
-
invalid_data = { 'summ' => ' ' }
|
66
|
-
issue = described_class.new(invalid_data)
|
67
|
-
expect(issue).not_to be_valid
|
68
|
-
end
|
69
|
-
end
|
70
|
-
|
71
|
-
describe '#add_tags' do
|
72
|
-
it 'adds additional tags to existing ones' do
|
73
|
-
issue = described_class.new(issue_data)
|
74
|
-
issue.add_tags(['new-label', 'another-label'])
|
75
|
-
|
76
|
-
expect(issue.tags).to include('bug', 'high-priority', 'new-label', 'another-label')
|
77
|
-
end
|
78
|
-
|
79
|
-
it 'removes duplicates when adding tags' do
|
80
|
-
issue = described_class.new(issue_data)
|
81
|
-
issue.add_tags(['bug', 'new-label'])
|
82
|
-
|
83
|
-
expect(issue.tags.count('bug')).to eq(1)
|
84
|
-
expect(issue.tags).to include('new-label')
|
85
|
-
end
|
86
|
-
end
|
87
|
-
|
88
|
-
describe 'site integration' do
|
89
|
-
let(:github_site) do
|
90
|
-
# Mock the Octokit client to avoid real API calls
|
91
|
-
mock_client = double('client')
|
92
|
-
allow(mock_client).to receive(:auto_paginate=)
|
93
|
-
|
94
|
-
# Mock milestone for version conversion
|
95
|
-
mock_milestone = double('milestone', title: '1.0.0', number: 1)
|
96
|
-
allow(mock_client).to receive(:milestones).with(any_args).and_return([mock_milestone])
|
97
|
-
allow(Octokit::Client).to receive(:new).and_return(mock_client)
|
98
|
-
allow_any_instance_of(Issuer::Sites::GitHub).to receive(:detect_github_token).and_return('test-token')
|
99
|
-
Issuer::Sites::GitHub.new(token: 'test-token')
|
100
|
-
end
|
101
|
-
|
102
|
-
it 'can be translated to GitHub API parameters via site' do
|
103
|
-
issue = described_class.new(issue_data)
|
104
|
-
params = github_site.convert_issue_to_site_params(issue, "test/repo")
|
105
|
-
|
106
|
-
expect(params[:title]).to eq('Test issue title')
|
107
|
-
expect(params[:body]).to eq('Test issue description')
|
108
|
-
expect(params[:labels]).to eq(['bug', 'high-priority'])
|
109
|
-
expect(params[:assignee]).to eq('testuser')
|
110
|
-
expect(params[:milestone]).to eq(1)
|
111
|
-
end
|
112
|
-
|
113
|
-
it 'handles missing optional fields when translated via site' do
|
114
|
-
minimal_data = { 'summ' => 'Title only' }
|
115
|
-
issue = described_class.new(minimal_data)
|
116
|
-
params = github_site.convert_issue_to_site_params(issue, "test/repo")
|
117
|
-
|
118
|
-
expect(params[:title]).to eq('Title only')
|
119
|
-
expect(params[:body]).to eq('')
|
120
|
-
expect(params).not_to have_key(:labels)
|
121
|
-
expect(params).not_to have_key(:assignee)
|
122
|
-
expect(params).not_to have_key(:milestone)
|
123
|
-
end
|
124
|
-
end
|
125
|
-
|
126
|
-
describe '.from_array' do
|
127
|
-
it 'creates multiple Issue objects from array' do
|
128
|
-
issues_array = [
|
129
|
-
{ 'summ' => 'First issue' },
|
130
|
-
{ 'summ' => 'Second issue' }
|
131
|
-
]
|
132
|
-
|
133
|
-
issues = described_class.from_array(issues_array, defaults)
|
134
|
-
|
135
|
-
expect(issues.length).to eq(2)
|
136
|
-
expect(issues.first.summ).to eq('First issue')
|
137
|
-
expect(issues.last.summ).to eq('Second issue')
|
138
|
-
end
|
139
|
-
end
|
140
|
-
|
141
|
-
describe '.valid_issues_from_array' do
|
142
|
-
it 'returns only valid issues' do
|
143
|
-
issues_array = [
|
144
|
-
{ 'summ' => 'Valid issue' },
|
145
|
-
{ 'desc' => 'Invalid - no title' },
|
146
|
-
{ 'summ' => 'Another valid issue' }
|
147
|
-
]
|
148
|
-
|
149
|
-
valid_issues = described_class.valid_issues_from_array(issues_array)
|
150
|
-
|
151
|
-
expect(valid_issues.length).to eq(2)
|
152
|
-
expect(valid_issues.map(&:summ)).to eq(['Valid issue', 'Another valid issue'])
|
153
|
-
end
|
154
|
-
end
|
155
|
-
|
156
|
-
describe 'new properties support' do
|
157
|
-
it 'supports body field instead of desc (legacy support)' do
|
158
|
-
new_format = { 'summ' => 'Title', 'body' => 'New body format' }
|
159
|
-
issue = described_class.new(new_format)
|
160
|
-
|
161
|
-
expect(issue.body).to eq('New body format')
|
162
|
-
end
|
163
|
-
|
164
|
-
it 'prefers body over desc when both are present' do
|
165
|
-
mixed_format = { 'summ' => 'Title', 'body' => 'New body', 'desc' => 'Old desc' }
|
166
|
-
issue = described_class.new(mixed_format)
|
167
|
-
|
168
|
-
expect(issue.body).to eq('New body')
|
169
|
-
end
|
170
|
-
|
171
|
-
it 'supports stub property' do
|
172
|
-
stub_data = { 'summ' => 'Title', 'stub' => true }
|
173
|
-
issue = described_class.new(stub_data)
|
174
|
-
|
175
|
-
expect(issue.stub).to be true
|
176
|
-
end
|
177
|
-
|
178
|
-
it 'allows body to be modified' do
|
179
|
-
issue = described_class.new(issue_data)
|
180
|
-
expect { issue.body = 'Modified body' }.not_to raise_error
|
181
|
-
expect(issue.body).to eq('Modified body')
|
182
|
-
end
|
183
|
-
end
|
184
|
-
end
|