Skip to content

Commit 1ae36b7

Browse files
committed
test: add auth integration tests
Add tests of the bundle web server with no auth and with a 'fixed' auth configuration. Exercise cases where the user provides no credentials, incorrect credentials, and correct credentials and the expected bundle server responses for each. Signed-off-by: Victoria Dye <[email protected]>
1 parent cd37b45 commit 1ae36b7

File tree

5 files changed

+113
-3
lines changed

5 files changed

+113
-3
lines changed
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
Feature: Auth configuration on the web server
2+
3+
Background: The bundle server has an initialized route
4+
Given no bundle server repository exists at route 'integration/auth'
5+
Given a new remote repository with main branch 'main'
6+
Given the remote is cloned
7+
Given 5 commits are pushed to the remote branch 'main'
8+
Given a bundle server repository is created at route 'integration/auth' for the remote
9+
10+
Scenario: With no auth config, bundle list can be accessed anonymously
11+
Given the bundle web server was started at port 8080
12+
When I request the bundle list
13+
Then the response code is 200
14+
Then the response is a valid bundle list
15+
16+
Scenario: If basic auth is required but none is sent, get a 401
17+
Given an auth config with username 'my_username' and password 'p4sSW0rD!'
18+
Given the bundle web server was started at port 8080 with auth config
19+
When I request the bundle list
20+
Then the response code is 401
21+
Then the response is empty
22+
23+
Scenario: If basic auth is required and we send bad credentials, get a 404
24+
Given an auth config with username 'my_username' and password 'p4sSW0rD!'
25+
Given the bundle web server was started at port 8080 with auth config
26+
When I request the bundle list with username 'my_userName' and password 'password!'
27+
Then the response code is 404
28+
Then the response is empty
29+
30+
Scenario: If basic auth is required and we send the right credentials, can access the bundle list
31+
Given an auth config with username 'my_username' and password 'p4sSW0rD!'
32+
Given the bundle web server was started at port 8080 with auth config
33+
When I request the bundle list with username 'my_username' and password 'p4sSW0rD!'
34+
Then the response code is 200
35+
Then the response is a valid bundle list
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import { IntegrationBundleServerWorld } from '../support/world'
2+
import { Given } from '@cucumber/cucumber'
3+
import * as fs from 'fs'
4+
import * as path from 'path'
5+
import * as crypto from 'crypto';
6+
7+
Given('an auth config with username {string} and password {string}',
8+
async function (this: IntegrationBundleServerWorld, user: string, pass: string) {
9+
const config = {
10+
"mode": "fixed",
11+
"parameters": {
12+
"username": user,
13+
"passwordHash": crypto.createHash('sha256').update(pass).digest('hex')
14+
}
15+
}
16+
fs.writeFileSync(path.join(this.trashDirectory, "auth-config.json"), JSON.stringify(config))
17+
}
18+
)
19+
20+
Given('the bundle web server was started at port {int} with auth config',
21+
async function (this: IntegrationBundleServerWorld, port: number) {
22+
await this.bundleServer.startWebServer(port, path.join(this.trashDirectory, "auth-config.json"))
23+
}
24+
)

test/integration/features/step_definitions/bundleServer.ts

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import * as assert from 'assert'
22
import { IntegrationBundleServerWorld } from '../support/world'
3-
import { Given, Then } from '@cucumber/cucumber'
3+
import { Given, When, Then } from '@cucumber/cucumber'
44
import * as utils from '../../../shared/support/utils'
55
import * as fs from 'fs'
66

@@ -18,6 +18,27 @@ Given('no bundle server repository exists at route {string}', async function (th
1818
}
1919
})
2020

21+
When('I request the bundle list', async function (this: IntegrationBundleServerWorld) {
22+
this.requestResponse = await fetch(this.bundleServer.bundleUri(), {
23+
method: 'GET',
24+
headers: {
25+
Accept: 'text/plain',
26+
},
27+
});
28+
})
29+
30+
When('I request the bundle list with username {string} and password {string}',
31+
async function (this: IntegrationBundleServerWorld, user: string, pass: string) {
32+
this.requestResponse = await fetch(this.bundleServer.bundleUri(), {
33+
method: 'GET',
34+
headers: {
35+
Accept: 'text/plain',
36+
Authorization: 'Basic ' + Buffer.from(`${user}:${pass}`, 'utf8').toString('base64')
37+
},
38+
});
39+
}
40+
)
41+
2142
Then('a bundle server repository exists at route {string}', async function (this: IntegrationBundleServerWorld, route: string) {
2243
var repoRoot = utils.repoRoot(route)
2344
assert.equal(fs.existsSync(repoRoot), true)
@@ -71,3 +92,28 @@ Then('the route exists in the routes file', async function (this: IntegrationBun
7192
throw new Error("Route not set")
7293
}
7394
})
95+
96+
Then('the response code is {int}', async function (this: IntegrationBundleServerWorld, code: number) {
97+
if (!this.requestResponse) {
98+
throw new Error("Request response not set")
99+
}
100+
assert.strictEqual(this.requestResponse.status, code)
101+
})
102+
103+
Then('the response is a valid bundle list', async function (this: IntegrationBundleServerWorld) {
104+
if (!this.requestResponse) {
105+
throw new Error("Request response not set")
106+
}
107+
108+
const data = await this.requestResponse.text()
109+
assert.notStrictEqual(data, "")
110+
})
111+
112+
Then('the response is empty', async function (this: IntegrationBundleServerWorld) {
113+
if (!this.requestResponse) {
114+
throw new Error("Request response not set")
115+
}
116+
117+
const data = await this.requestResponse.text()
118+
assert.strictEqual(data, "")
119+
})

test/integration/features/support/world.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ export class IntegrationBundleServerWorld extends BundleServerWorldBase {
1010
local: ClonedRepository | undefined
1111

1212
commandResult: child_process.SpawnSyncReturns<Buffer> | undefined
13+
requestResponse: Response | undefined
1314

1415
runCommand(commandArgs: string): void {
1516
this.commandResult = child_process.spawnSync(`${this.parameters.bundleServerCommand} ${commandArgs}`, [], { shell: true })

test/shared/classes/bundleServer.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,15 @@ export class BundleServer {
2121
this.bundleWebServerCmd = bundleWebServerCmd
2222
}
2323

24-
async startWebServer(port: number): Promise<void> {
24+
async startWebServer(port: number, authConfig: string = ""): Promise<void> {
2525
if (this.webServerProcess) {
2626
throw new Error("Tried to start web server, but web server is already running")
2727
}
28-
const webServerProcess = child_process.spawn(this.bundleWebServerCmd, ["--port", String(port)])
28+
let args = ["--port", String(port)]
29+
if (authConfig !== "") {
30+
args = args.concat(["--auth-config", authConfig])
31+
}
32+
const webServerProcess = child_process.spawn(this.bundleWebServerCmd, args)
2933
this.webServerProcess = webServerProcess
3034
this.bundleUriBase = `http://localhost:${port}/`
3135

0 commit comments

Comments
 (0)