108 lines
3.8 KiB
Go
108 lines
3.8 KiB
Go
package builder
|
|
|
|
import (
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
func TestNpmrcRendersRegistryAndTokenForTheScope(t *testing.T) {
|
|
n := Npmrc{
|
|
Scope: "@novox",
|
|
Registry: "https://forge.invalid/api/packages/novox/npm/",
|
|
Token: "a-token",
|
|
}
|
|
got, err := n.File()
|
|
if err != nil {
|
|
t.Fatalf("a complete credential did not render: %v", err)
|
|
}
|
|
if !strings.Contains(got, "@novox:registry=https://forge.invalid/api/packages/novox/npm/") {
|
|
t.Fatalf("the scope's registry line is missing:\n%s", got)
|
|
}
|
|
// The auth line is keyed by the URL without its scheme, or npm never sends the token.
|
|
if !strings.Contains(got, "//forge.invalid/api/packages/novox/npm/:_authToken=a-token") {
|
|
t.Fatalf("the auth line does not match the registry key:\n%s", got)
|
|
}
|
|
}
|
|
|
|
func TestNpmrcAddsATrailingSlashSoTheAuthKeyMatches(t *testing.T) {
|
|
n := Npmrc{Scope: "@novox", Registry: "https://forge.invalid/api/packages/novox/npm", Token: "t"}
|
|
got, err := n.File()
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if !strings.Contains(got, "registry=https://forge.invalid/api/packages/novox/npm/\n") {
|
|
t.Fatalf("a missing trailing slash was not normalised:\n%s", got)
|
|
}
|
|
}
|
|
|
|
func TestNpmrcRefusesTheHalfConfigured(t *testing.T) {
|
|
cases := map[string]Npmrc{
|
|
"scope without @": {Scope: "novox", Registry: "https://x.invalid/", Token: "t"},
|
|
"registry not http": {Scope: "@novox", Registry: "ftp://x.invalid/", Token: "t"},
|
|
"no token": {Scope: "@novox", Registry: "https://x.invalid/", Token: ""},
|
|
}
|
|
for name, n := range cases {
|
|
if _, err := n.File(); err == nil {
|
|
t.Fatalf("%s rendered an .npmrc rather than refusing", name)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestNpmrcDisabledUntilThereIsARegistry(t *testing.T) {
|
|
if (Npmrc{}).Enabled() {
|
|
t.Fatal("an empty credential reported itself usable")
|
|
}
|
|
if (Npmrc{Scope: "@novox"}).Enabled() {
|
|
t.Fatal("a scope with no registry reported itself usable")
|
|
}
|
|
if !(Npmrc{Scope: "@novox", Registry: "https://x.invalid/"}).Enabled() {
|
|
t.Fatal("a scope and a registry did not count as usable")
|
|
}
|
|
}
|
|
|
|
// The credential reaches an image build as an .npmrc inside the build context — for a Dockerfile to
|
|
// COPY in a stage it does not publish — and the build runs on the host network so a RUN resolving the
|
|
// registry reaches it where the binding says (novox/hq ADR 0076). Not a buildkit secret, because this
|
|
// machine's docker may carry no buildx.
|
|
|
|
const aPackage = `{"module":"mesh-sdk","version":"1",
|
|
"build":{"artifacts":[{"name":"lib","kind":"package","language":"typescript"}]},
|
|
"resources":[]}`
|
|
|
|
// A package is compiled on a public base and published to the mesh's package registry by version,
|
|
// with nothing pushed to the artifact store and the credential mounted, not baked (novox/hq ADR 0076).
|
|
|
|
func TestNpmrcRendersBasicAuthWhenGivenAUserAndPassword(t *testing.T) {
|
|
n := Npmrc{
|
|
Scope: "@novox",
|
|
Registry: "http://forge.invalid:3000/api/packages/novox/npm/",
|
|
Username: "mesh_anchor_builder",
|
|
Password: "s3cret",
|
|
}
|
|
got, err := n.File()
|
|
if err != nil {
|
|
t.Fatalf("basic-auth credential did not render: %v", err)
|
|
}
|
|
key := "//forge.invalid:3000/api/packages/novox/npm/"
|
|
if !strings.Contains(got, key+":username=mesh_anchor_builder\n") {
|
|
t.Fatalf("username line missing:\n%s", got)
|
|
}
|
|
// npm reads the password base64-encoded.
|
|
if !strings.Contains(got, key+":_password=czNjcmV0\n") {
|
|
t.Fatalf("base64 password line missing or wrong:\n%s", got)
|
|
}
|
|
if !strings.Contains(got, key+":always-auth=true\n") {
|
|
t.Fatalf("always-auth missing, so reads would go unauthenticated:\n%s", got)
|
|
}
|
|
if strings.Contains(got, "_authToken") {
|
|
t.Fatalf("a token line was rendered for a basic-auth credential:\n%s", got)
|
|
}
|
|
}
|
|
|
|
func TestNpmrcRefusesWhenGivenNeitherTokenNorPassword(t *testing.T) {
|
|
n := Npmrc{Scope: "@novox", Registry: "http://x.invalid/npm/", Username: "u"}
|
|
if _, err := n.File(); err == nil {
|
|
t.Fatal("a username with no password rendered an .npmrc")
|
|
}
|
|
}
|