-
Notifications
You must be signed in to change notification settings - Fork 44
WIP Apply overview related patches from fork #453
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,7 @@ | ||
name: Build | ||
|
||
on: | ||
workflow_dispatch: {} | ||
push: | ||
branches: | ||
- '**' | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -7,10 +7,11 @@ Stay in the flow by using Atlassian for VSCode to start work on a JIRA issue, ra | |
|
||
[**Download now**](https://marketplace.visualstudio.com/items?itemName=Atlassian.atlascode&ssr=false#overview) | ||
|
||
## [Devsphere specific changelog](/DEVSPHERE_CHANGELOG.md) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Remove these logs: these are not useful in upstream |
||
We're adding certain features & updates to this fork which may or may not be suitable to push upstream. Refer to the [Devsphere specific changelog](/DEVSPHERE_CHANGELOG.md) to get more context. | ||
|
||
## Usage | ||
|
||
|
||
### Getting Started | ||
|
||
- Make sure you have VS Code version 1.77.0 or above | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -98,6 +98,16 @@ | |
}, | ||
"category": "Atlassian" | ||
}, | ||
{ | ||
"command": "atlascode.devsphere.review.initialise", | ||
"title": "Initialise Devsphere Review Settings", | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Rename to "Unset Pull Request Review mode" |
||
"category": "Atlassian" | ||
}, | ||
{ | ||
"command": "atlascode.devsphere.custom.reset", | ||
"title": "Reset Devsphere Custom Configuration", | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Rename to "Set Pull Request Review mode" |
||
"category": "Atlassian" | ||
}, | ||
{ | ||
"command": "atlascode.jira.searchIssues", | ||
"title": "Search Jira Issue Results", | ||
|
@@ -402,6 +412,14 @@ | |
"title": "Disable Help Explorer", | ||
"category": "Atlassian" | ||
}, | ||
{ | ||
"command": "atlascode.bitbucket.pullRequestsOverview.refresh", | ||
"title": "Refresh", | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Rename to "Refresh Pull Request Overview Panel" |
||
"icon": { | ||
"light": "resources/light/refresh.svg", | ||
"dark": "resources/dark/refresh.svg" | ||
} | ||
}, | ||
{ | ||
"command": "atlascode.showOnboardingFlow", | ||
"title": "Show Onboarding Flow", | ||
|
@@ -432,7 +450,12 @@ | |
{ | ||
"id": "atlascode.views.bb.pullrequestsTreeView", | ||
"name": "Bitbucket pull requests", | ||
"when": "atlascode:bitbucketExplorerEnabled && config.atlascode.bitbucket.enabled" | ||
"when": "atlascode:bitbucketExplorerEnabled && config.atlascode.bitbucket.enabled && config.atlascode.bitbucket.explorer.repositoryBasedPullRequestView.enabled" | ||
}, | ||
{ | ||
"id": "atlascode.views.bb.pullRequestsOverviewTreeView", | ||
"name": "Bitbucket pull requests overview", | ||
"when": "atlascode:bitbucketExplorerEnabled && config.atlascode.bitbucket.enabled && config.atlascode.bitbucket.explorer.pullRequestsOverview.enabled" | ||
}, | ||
{ | ||
"id": "atlascode.views.bb.pipelinesTreeView", | ||
|
@@ -579,6 +602,11 @@ | |
{ | ||
"command": "atlascode.disableHelpExplorer", | ||
"when": "view == atlascode.views.helpTreeView" | ||
}, | ||
{ | ||
"command": "atlascode.bitbucket.pullRequestsOverview.refresh", | ||
"when": "view == atlascode.views.bb.pullRequestsOverviewTreeView", | ||
"group": "navigation@1" | ||
} | ||
], | ||
"view/item/context": [ | ||
|
@@ -1105,6 +1133,18 @@ | |
"description": "Enables the Bitbucket Pull Request Explorer", | ||
"scope": "window" | ||
}, | ||
"atlascode.bitbucket.explorer.repositoryBasedPullRequestView.enabled": { | ||
"type": "boolean", | ||
"default": true, | ||
"description": "Enable repository based pull requests tree view", | ||
"scope": "window" | ||
}, | ||
"atlascode.bitbucket.explorer.pullRequestsOverview.enabled": { | ||
"type": "boolean", | ||
"default": true, | ||
"description": "Enable pull requests overview tree view", | ||
"scope": "window" | ||
}, | ||
"atlascode.bitbucket.explorer.nestFilesEnabled": { | ||
"type": "boolean", | ||
"default": true, | ||
|
@@ -1408,4 +1448,4 @@ | |
"webpack-node-externals": "^3.0.0" | ||
}, | ||
"packageManager": "[email protected]+sha512.a6b2f7906b721bba3d67d4aff083df04dad64c399707841b7acf00f6b133b7ac24255f2652fa22ae3534329dc6180534e98d17432037ff6fd140556e2bb3137e" | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,150 @@ | ||
// Mock crypto module at the top | ||
class MockHash { | ||
private data: string = ''; | ||
|
||
update(data: any): this { | ||
this.data += data.toString(); | ||
return this; | ||
} | ||
|
||
digest(): Buffer { | ||
// Return a predictable hash for testing | ||
const hash = Buffer.alloc(32); | ||
for (let i = 0; i < 32; i++) { | ||
hash[i] = (this.data.charCodeAt(i % this.data.length) + i) % 256; | ||
} | ||
return hash; | ||
} | ||
} | ||
|
||
jest.mock('crypto', () => ({ | ||
default: { | ||
createHash: () => new MockHash(), | ||
randomBytes: (size: number) => { | ||
// Return predictable bytes for testing | ||
const buffer = Buffer.alloc(size); | ||
for (let i = 0; i < size; i++) { | ||
buffer[i] = i % 256; | ||
} | ||
return buffer; | ||
}, | ||
}, | ||
})); | ||
|
||
import { base64URLEncode, basicAuth, createVerifier, sha256 } from './strategyCrypto'; | ||
|
||
describe('strategyCrypto', () => { | ||
describe('basicAuth', () => { | ||
it('should create basic auth string with username and password', () => { | ||
const result = basicAuth('testuser', 'testpass'); | ||
expect(result).toBe('Basic dGVzdHVzZXI6dGVzdHBhc3M='); | ||
}); | ||
|
||
it('should handle empty username and password', () => { | ||
const result = basicAuth('', ''); | ||
expect(result).toBe('Basic Og=='); | ||
}); | ||
|
||
it('should handle special characters in username and password', () => { | ||
const result = basicAuth('[email protected]', 'p@ssw0rd!'); | ||
expect(result).toBe('Basic dXNlckBkb21haW4uY29tOnBAc3N3MHJkIQ=='); | ||
}); | ||
|
||
it('should handle unicode characters', () => { | ||
const result = basicAuth('用户', '密码'); | ||
expect(result).toContain('Basic '); | ||
expect(result.length).toBeGreaterThan('Basic '.length); | ||
}); | ||
}); | ||
|
||
describe('base64URLEncode', () => { | ||
it('should encode buffer to base64 URL safe string', () => { | ||
const buffer = Buffer.from('hello world'); | ||
const result = base64URLEncode(buffer); | ||
expect(result).toBe('aGVsbG8gd29ybGQ'); | ||
}); | ||
|
||
it('should replace URL unsafe characters', () => { | ||
// Create a buffer that will have + and / characters in base64 | ||
const buffer = Buffer.from('hello>world?test'); | ||
const result = base64URLEncode(buffer); | ||
expect(result).not.toContain('+'); | ||
expect(result).not.toContain('/'); | ||
expect(result).not.toContain('='); | ||
}); | ||
|
||
it('should handle empty buffer', () => { | ||
const buffer = Buffer.from(''); | ||
const result = base64URLEncode(buffer); | ||
expect(result).toBe(''); | ||
}); | ||
|
||
it('should handle binary data', () => { | ||
const buffer = Buffer.from([0x00, 0x01, 0x02, 0x03, 0xff]); | ||
const result = base64URLEncode(buffer); | ||
expect(result).toBe('AAECA_8'); // Corrected expected value | ||
}); | ||
}); | ||
|
||
describe('sha256', () => { | ||
it('should create sha256 hash from string', () => { | ||
const result = sha256('hello world'); | ||
expect(result).toBeInstanceOf(Buffer); | ||
expect(result.length).toBe(32); // SHA256 produces 32 bytes | ||
}); | ||
|
||
it('should create sha256 hash from buffer', () => { | ||
const buffer = Buffer.from('test data'); | ||
const result = sha256(buffer); | ||
expect(result).toBeInstanceOf(Buffer); | ||
expect(result.length).toBe(32); | ||
}); | ||
|
||
it('should produce consistent hash for same input', () => { | ||
const input = 'consistent input'; | ||
const result1 = sha256(input); | ||
const result2 = sha256(input); | ||
expect(result1.equals(result2)).toBe(true); | ||
}); | ||
|
||
it('should produce different hashes for different inputs', () => { | ||
const result1 = sha256('input1'); | ||
const result2 = sha256('input2'); | ||
expect(result1.equals(result2)).toBe(false); | ||
}); | ||
|
||
it('should handle empty string', () => { | ||
const result = sha256(''); | ||
expect(result).toBeInstanceOf(Buffer); | ||
expect(result.length).toBe(32); | ||
}); | ||
}); | ||
|
||
describe('createVerifier', () => { | ||
it('should create a verifier string', () => { | ||
const result = createVerifier(); | ||
expect(typeof result).toBe('string'); | ||
expect(result.length).toBeGreaterThan(0); | ||
}); | ||
|
||
it('should create consistent verifiers with mocked crypto', () => { | ||
const result1 = createVerifier(); | ||
const result2 = createVerifier(); | ||
// With our mock, results should be the same | ||
expect(result1).toBe(result2); | ||
}); | ||
|
||
it('should create URL-safe verifier string', () => { | ||
const result = createVerifier(); | ||
expect(result).not.toContain('+'); | ||
expect(result).not.toContain('/'); | ||
expect(result).not.toContain('='); | ||
}); | ||
|
||
it('should create verifier of expected length', () => { | ||
const result = createVerifier(); | ||
// 32 bytes base64URL encoded should be 43 characters (without padding) | ||
expect(result.length).toBe(43); | ||
}); | ||
}); | ||
}); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
import { encodePathParts } from './bbUtils'; | ||
|
||
describe('bbUtils', () => { | ||
describe('encodePathParts', () => { | ||
it('should encode path parts with special characters', () => { | ||
const path = 'folder/sub folder/file with spaces.txt'; | ||
const result = encodePathParts(path); | ||
expect(result).toBe('folder/sub%20folder/file%20with%20spaces.txt'); | ||
}); | ||
|
||
it('should handle paths with special URL characters', () => { | ||
const path = 'folder/sub&folder/file?param=value.txt'; | ||
const result = encodePathParts(path); | ||
expect(result).toBe('folder/sub%26folder/file%3Fparam%3Dvalue.txt'); | ||
}); | ||
|
||
it('should handle empty path parts', () => { | ||
const path = 'folder//subfolder'; | ||
const result = encodePathParts(path); | ||
expect(result).toBe('folder//subfolder'); | ||
}); | ||
|
||
it('should handle single folder name', () => { | ||
const path = 'folder name'; | ||
const result = encodePathParts(path); | ||
expect(result).toBe('folder%20name'); | ||
}); | ||
|
||
it('should handle empty string', () => { | ||
const path = ''; | ||
const result = encodePathParts(path); | ||
expect(result).toBe(''); | ||
}); | ||
|
||
it('should handle null/undefined input', () => { | ||
expect(encodePathParts(null as any)).toBe(undefined); | ||
expect(encodePathParts(undefined as any)).toBe(undefined); | ||
}); | ||
|
||
it('should handle paths with unicode characters', () => { | ||
const path = 'folder/测试文件/файл.txt'; | ||
const result = encodePathParts(path); | ||
expect(result).toBe('folder/%E6%B5%8B%E8%AF%95%E6%96%87%E4%BB%B6/%D1%84%D0%B0%D0%B9%D0%BB.txt'); | ||
}); | ||
}); | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note to self: Why is this needed?