Skip to content

Commit 97fc19f

Browse files
committed
Fall back to numeric id in project URLs
ProjectUrl built projects/<identifier> with no fallback, so a project whose identifier is empty produced projects/ (the index) instead of the project. Mirror WorkPackageUrl and use the numeric id, which is also a valid /projects/ address, when the identifier is missing.
1 parent 9becbff commit 97fc19f

2 files changed

Lines changed: 47 additions & 1 deletion

File tree

components/routes/routes.go

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,12 @@ func WorkPackageUrl(workPackage *models.WorkPackage) *url.URL {
2828

2929
func ProjectUrl(project *models.Project) *url.URL {
3030
routeUrl := *host
31-
routeUrl.Path = fmt.Sprintf("projects/%s", project.Identifier)
31+
// Current servers always set identifier, but fall back to the numeric id
32+
// (also a valid /projects/ address) when it is missing.
33+
identifier := project.Identifier
34+
if identifier == "" {
35+
identifier = strconv.FormatUint(project.Id, 10)
36+
}
37+
routeUrl.Path = fmt.Sprintf("projects/%s", identifier)
3238
return &routeUrl
3339
}

components/routes/routes_test.go

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
package routes_test
2+
3+
import (
4+
"net/url"
5+
"testing"
6+
7+
"github.com/opf/openproject-cli/components/routes"
8+
"github.com/opf/openproject-cli/models"
9+
)
10+
11+
func initHost(t *testing.T) {
12+
t.Helper()
13+
host, err := url.Parse("https://op.example.com")
14+
if err != nil {
15+
t.Fatal(err)
16+
}
17+
routes.Init(host)
18+
}
19+
20+
func TestProjectUrl_UsesIdentifierWhenPresent(t *testing.T) {
21+
initHost(t)
22+
23+
got := routes.ProjectUrl(&models.Project{Id: 42, Identifier: "my-project"}).String()
24+
want := "https://op.example.com/projects/my-project"
25+
if got != want {
26+
t.Errorf("ProjectUrl = %q, want %q", got, want)
27+
}
28+
}
29+
30+
// A project whose identifier is missing (older servers, minimal payloads) must
31+
// still produce a working URL by falling back to the numeric id.
32+
func TestProjectUrl_EmptyIdentifierFallsBackToId(t *testing.T) {
33+
initHost(t)
34+
35+
got := routes.ProjectUrl(&models.Project{Id: 42, Identifier: ""}).String()
36+
want := "https://op.example.com/projects/42"
37+
if got != want {
38+
t.Errorf("ProjectUrl = %q, want %q", got, want)
39+
}
40+
}

0 commit comments

Comments
 (0)