Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-pages.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'internal/redirects/matching_test.go')
-rw-r--r--internal/redirects/matching_test.go355
1 files changed, 344 insertions, 11 deletions
diff --git a/internal/redirects/matching_test.go b/internal/redirects/matching_test.go
index 23815b97..3938b680 100644
--- a/internal/redirects/matching_test.go
+++ b/internal/redirects/matching_test.go
@@ -1,6 +1,7 @@
package redirects
import (
+ "net/url"
"testing"
"github.com/stretchr/testify/require"
@@ -56,7 +57,7 @@ var testsWithoutPlaceholders = map[string]testCaseData{
},
}
-func Test_matchesRule(t *testing.T) {
+func testMatchesRule(t *testing.T) {
t.Setenv(feature.RedirectsPlaceholders.EnvVariable, "true")
tests := mergeTestSuites(testsWithoutPlaceholders, map[string]testCaseData{
@@ -68,11 +69,12 @@ func Test_matchesRule(t *testing.T) {
expectMatch: true,
expectedPath: "/bar/",
},
+ // Since we are treating path as an entire path, so // is considered domain name
"multiple_leading_slashes": {
rule: "/foo/ /bar/",
path: "//foo",
- expectMatch: true,
- expectedPath: "/bar/",
+ expectMatch: false,
+ expectedPath: "",
},
"multiple_slashes_in_middle": {
rule: "/foo/bar /baz/",
@@ -81,6 +83,13 @@ func Test_matchesRule(t *testing.T) {
expectedPath: "/baz/",
},
+ "schema_host_from_url": {
+ rule: "http://pages.example.io/foo /baz/",
+ path: "http://pages.example.io/foo",
+ expectMatch: true,
+ expectedPath: "/baz/",
+ },
+
"splat_match": {
rule: "/foo/*/bar /foo/:splat/qux",
path: "/foo/baz/bar",
@@ -153,12 +162,6 @@ func Test_matchesRule(t *testing.T) {
expectMatch: true,
expectedPath: "/qux/foo/bar",
},
- "multiple_splats": {
- rule: "/foo/*/bar/*/baz /qux/:splat",
- path: "/foo/hello/bar/world/baz",
- expectMatch: true,
- expectedPath: "/qux/hello",
- },
"duplicate_splat_replacements": {
rule: "/foo/* /qux/:splat/:splat",
path: "/foo/hello",
@@ -301,13 +304,25 @@ func Test_matchesRule(t *testing.T) {
rules, err := netlifyRedirects.ParseString(tt.rule)
require.NoError(t, err)
- isMatch, path := matchesRule(&rules[0], tt.path)
+ parsedURL, err := url.Parse(tt.path)
+ require.NoError(t, err)
+
+ isMatch, path := matchesRule(&rules[0], parsedURL)
require.Equal(t, tt.expectMatch, isMatch)
require.Equal(t, tt.expectedPath, path)
})
}
}
+func Test_matchesRule(t *testing.T) {
+ testMatchesRule(t)
+}
+
+func Test_matchesNonDomainRule_DomainRedirects_enabled(t *testing.T) {
+ t.Setenv(feature.DomainRedirects.EnvVariable, "true")
+ testMatchesRule(t)
+}
+
// Tests matching behavior when the `FF_ENABLE_PLACEHOLDERS`
// feature flag is not enabled. These tests can be removed when the
// `FF_ENABLE_PLACEHOLDERS` flag is removed.
@@ -343,7 +358,325 @@ func Test_matchesRule_NoPlaceholders(t *testing.T) {
rules, err := netlifyRedirects.ParseString(tt.rule)
require.NoError(t, err)
- isMatch, path := matchesRule(&rules[0], tt.path)
+ parsedURL, err := url.Parse(tt.path)
+ require.NoError(t, err)
+
+ isMatch, path := matchesRule(&rules[0], parsedURL)
+ require.Equal(t, tt.expectMatch, isMatch)
+ require.Equal(t, tt.expectedPath, path)
+ })
+ }
+}
+
+// Tests matching behavior when the `FF_ENABLE_DOMAIN_REDIRECT`
+// feature flag is enabled.
+func Test_matchesDomainRule(t *testing.T) {
+ t.Setenv(feature.RedirectsPlaceholders.EnvVariable, "true")
+ t.Setenv(feature.DomainRedirects.EnvVariable, "true")
+
+ tests := map[string]testCaseData{
+ "exact_path_match": {
+ rule: "/foo/ http://test.example.io/bar/",
+ path: "http://pages.example.io/foo/",
+ expectMatch: true,
+ expectedPath: "http://test.example.io/bar/",
+ },
+ "exact_url_match": {
+ rule: "http://pages.example.io/foo/ http://test.example.io/bar/",
+ path: "http://pages.example.io/foo/",
+ expectMatch: true,
+ expectedPath: "http://test.example.io/bar/",
+ },
+ "single_trailing_slash": {
+ rule: "http://pages.example.io/foo/ http://test.example.io/bar/",
+ path: "http://pages.example.io/foo",
+ expectMatch: true,
+ expectedPath: "http://test.example.io/bar/",
+ },
+ "ignore_missing_slash": {
+ rule: "http://pages.example.io/foo http://test.example.io/bar/",
+ path: "http://pages.example.io/foo/",
+ expectMatch: true,
+ expectedPath: "http://test.example.io/bar/",
+ },
+ "no_match": {
+ rule: "http://pages.example.io/foo http://test.example.io/bar/",
+ path: "http://pages.example.io/foo/bar",
+ expectMatch: false,
+ expectedPath: "",
+ },
+
+ // Note: the following 3 cases behave differently when
+ // placeholders are disabled. See the similar test cases below.
+ "multiple_trailing_slashes": {
+ rule: "http://pages.example.io/foo/ http://test.example.io/bar/",
+ path: "http://pages.example.io/foo//",
+ expectMatch: true,
+ expectedPath: "http://test.example.io/bar/",
+ },
+ "multiple_slashes_in_middle": {
+ rule: "http://pages.example.io/foo/bar http://test.example.io/baz/",
+ path: "http://pages.example.io/foo//bar",
+ expectMatch: true,
+ expectedPath: "http://test.example.io/baz/",
+ },
+
+ "domain_redirect_different_protocol": {
+ rule: "http://pages.example.io/foo/bar https://test.example.io/baz/",
+ path: "http://pages.example.io/foo//bar",
+ expectMatch: true,
+ expectedPath: "https://test.example.io/baz/",
+ },
+
+ "splat_match": {
+ rule: "http://pages.example.io/foo/*/bar http://test.example.io/foo/:splat/qux",
+ path: "http://pages.example.io/foo/baz/bar",
+ expectMatch: true,
+ expectedPath: "http://test.example.io/foo/baz/qux",
+ },
+ "splat_match_multiple_segments": {
+ rule: "http://pages.example.io/foo/*/bar http://test.example.io/foo/:splat/qux",
+ path: "http://pages.example.io/foo/hello/world/bar",
+ expectMatch: true,
+ expectedPath: "http://test.example.io/foo/hello/world/qux",
+ },
+ "splat_match_ignore_trailing_slash": {
+ rule: "http://pages.example.io/foo/*/bar http://test.example.io/foo/:splat/qux",
+ path: "http://pages.example.io/foo/baz/bar/",
+ expectMatch: true,
+ expectedPath: "http://test.example.io/foo/baz/qux",
+ },
+ "splat_match_end": {
+ rule: "http://pages.example.io/foo/* http://test.example.io/qux/:splat",
+ path: "http://pages.example.io/foo/baz/bar",
+ expectMatch: true,
+ expectedPath: "http://test.example.io/qux/baz/bar",
+ },
+ "splat_match_end_with_slash": {
+ rule: "http://pages.example.io/foo/* http://test.example.io/qux/:splat",
+ path: "http://pages.example.io/foo/baz/bar/",
+ expectMatch: true,
+ expectedPath: "http://test.example.io/qux/baz/bar/",
+ },
+ "splat_match_beginning": {
+ rule: "http://pages.example.io/*/baz/bar http://test.example.io/qux/:splat",
+ path: "http://pages.example.io/foo/baz/bar",
+ expectMatch: true,
+ expectedPath: "http://test.example.io/qux/foo",
+ },
+ "splat_match_empty_suffix": {
+ rule: "http://pages.example.io/foo/* http://test.example.io/qux/:splat",
+ path: "http://pages.example.io/foo/",
+ expectMatch: true,
+ expectedPath: "http://test.example.io/qux/",
+ },
+ "splat_consumes_trailing_slash": {
+ rule: "http://pages.example.io/foo/* http://test.example.io/qux/:splat",
+ path: "http://pages.example.io/foo",
+ expectMatch: true,
+ expectedPath: "http://test.example.io/qux/",
+ },
+ "splat_match_empty_prefix": {
+ rule: "http://pages.example.io/*/foo http://test.example.io/qux/:splat",
+ path: "http://pages.example.io/foo",
+ expectMatch: true,
+ expectedPath: "http://test.example.io/qux/",
+ },
+ "splat_mid_segment": {
+ rule: "http://pages.example.io/foo*bar http://test.example.io/qux/:splat",
+ path: "http://pages.example.io/foobazbar",
+ expectMatch: false,
+ expectedPath: "",
+ },
+ "splat_mid_segment_no_content": {
+ rule: "http://pages.example.io/foo*bar http://test.example.io/qux/:splat",
+ path: "http://pages.example.io/foobar",
+ expectMatch: false,
+ expectedPath: "",
+ },
+ "lone_splat": {
+ rule: "http://pages.example.io/* http://test.example.io/qux/:splat",
+ path: "http://pages.example.io/foo/bar",
+ expectMatch: true,
+ expectedPath: "http://test.example.io/qux/foo/bar",
+ },
+ "duplicate_splat_replacements": {
+ rule: "http://pages.example.io/foo/* http://test.example.io/qux/:splat/:splat",
+ path: "http://pages.example.io/foo/hello",
+ expectMatch: true,
+ expectedPath: "http://test.example.io/qux/hello/hello",
+ },
+ "splat_missing_path_segment_behavior": {
+ rule: "http://pages.example.io/foo/*/bar http://test.example.io/foo/:splat/qux",
+ path: "http://pages.example.io/foo/bar",
+ expectMatch: true,
+ expectedPath: "http://test.example.io/foo/qux",
+ },
+ "missing_splat_placeholder": {
+ rule: "http://pages.example.io/foo/ http://test.example.io/qux/:splat",
+ path: "http://pages.example.io/foo/",
+ expectMatch: true,
+ expectedPath: "http://test.example.io/qux/",
+ },
+ "placeholder_match": {
+ rule: "http://pages.example.io/foo/:year/:month/:day/bar http://test.example.io/qux/:year-:month-:day",
+ path: "http://pages.example.io/foo/2021/08/16/bar",
+ expectMatch: true,
+ expectedPath: "http://test.example.io/qux/2021-08-16",
+ },
+ "placeholder_match_end": {
+ rule: "http://pages.example.io/foo/:placeholder http://test.example.io/qux/:placeholder",
+ path: "http://pages.example.io/foo/bar",
+ expectMatch: true,
+ expectedPath: "http://test.example.io/qux/bar",
+ },
+ "placeholder_match_beginning": {
+ rule: "http://pages.example.io/:placeholder/foo http://test.example.io/qux/:placeholder",
+ path: "http://pages.example.io/baz/foo",
+ expectMatch: true,
+ expectedPath: "http://test.example.io/qux/baz",
+ },
+ "placeholder_no_multiple_segments": {
+ rule: "http://pages.example.io/foo/:placeholder/bar http://test.example.io/foo/:placeholder/qux",
+ path: "http://pages.example.io/foo/hello/world/bar",
+ expectMatch: false,
+ expectedPath: "",
+ },
+ "placeholder_at_beginning_no_content": {
+ rule: "http://pages.example.io/:placeholder/foo http://test.example.io/qux/:placeholder",
+ path: "http://pages.example.io/foo",
+ expectMatch: false,
+ expectedPath: "",
+ },
+ "placeholder_at_end_no_content": {
+ rule: "http://pages.example.io/foo/:placeholder http://test.example.io/qux/:placeholder",
+ path: "http://pages.example.io/foo/",
+ expectMatch: false,
+ expectedPath: "",
+ },
+ "placeholder_mid_segment_in_from": {
+ rule: "http://pages.example.io/foo:placeholder http://test.example.io/qux/:placeholder",
+ path: "http://pages.example.io/foorbar",
+ expectMatch: false,
+ expectedPath: "",
+ },
+ "placeholder_mid_segment_in_to": {
+ rule: "http://pages.example.io/foo/:placeholder http://test.example.io/qux/bar:placeholder",
+ path: "http://pages.example.io/foo/baz",
+ expectMatch: true,
+ expectedPath: "http://test.example.io/qux/barbaz",
+ },
+ "placeholder_missing_replacement_with_substring": {
+ rule: "http://pages.example.io/:foo http://test.example.io/:foobar",
+ path: "http://pages.example.io/baz",
+ expectMatch: true,
+ expectedPath: "http://test.example.io/",
+ },
+ "placeholder_mid_segment_no_content": {
+ rule: "http://pages.example.io/foo:placeholder http://test.example.io/qux/:splat",
+ path: "http://pages.example.io/foo",
+ expectMatch: false,
+ expectedPath: "",
+ },
+ "placeholder_name_substring": {
+ rule: "http://pages.example.io/foo/:foo/:foobar http://test.example.io/qux/:foo/:foobar",
+ path: "http://pages.example.io/foo/baz/quux",
+ expectMatch: true,
+ expectedPath: "http://test.example.io/qux/baz/quux",
+ },
+ "lone_placeholder": {
+ rule: "http://pages.example.io/:placeholder http://test.example.io/qux/:placeholder",
+ path: "http://pages.example.io/foo",
+ expectMatch: true,
+ expectedPath: "http://test.example.io/qux/foo",
+ },
+ "duplicate_placeholders": {
+ rule: "http://pages.example.io/foo/:placeholder/bar/:placeholder/baz http://test.example.io/qux/:placeholder",
+ path: "http://pages.example.io/foo/hello/bar/world/baz",
+ expectMatch: true,
+ expectedPath: "http://test.example.io/qux/hello",
+ },
+ "duplicate_placeholder_replacements": {
+ rule: "http://pages.example.io/foo/:placeholder http://test.example.io/qux/:placeholder/:placeholder",
+ path: "http://pages.example.io/foo/hello",
+ expectMatch: true,
+ expectedPath: "http://test.example.io/qux/hello/hello",
+ },
+ "splat_and_placeholder_named_splat": {
+ rule: "http://pages.example.io/foo/*/bar/:splat http://test.example.io/qux/:splat",
+ path: "http://pages.example.io/foo/hello/bar/world",
+ expectMatch: true,
+ expectedPath: "http://test.example.io/qux/hello",
+ },
+ "placeholder_named_splat_and_splat": {
+ rule: "http://pages.example.io/foo/:splat/bar/* http://test.example.io/qux/:splat",
+ path: "http://pages.example.io/foo/hello/bar/world",
+ expectMatch: true,
+ expectedPath: "http://test.example.io/qux/hello",
+ },
+
+ // Note: These differ slightly from Netlify's matching behavior.
+ // GitLab replaces _all_ placeholders in the "to" path, even if
+ // the placeholder doesn't have corresponding match in the "from".
+ // Netlify only replaces placeholders that appear in the "from".
+ "missing_placeholder_exact_match": {
+ rule: "http://pages.example.io/foo/ http://test.example.io/qux/:placeholder",
+ path: "http://pages.example.io/foo/",
+ expectMatch: true,
+
+ // Netlify would instead redirect to "/qux/:placeholder"
+ expectedPath: "http://test.example.io/qux/",
+ },
+ "missing_placeholder_nonexact_match": {
+ rule: "http://pages.example.io/foo/:placeholderA http://test.example.io/qux/:placeholderB",
+ path: "http://pages.example.io/foo/bar",
+ expectMatch: true,
+
+ // Netlify would instead redirect to "/qux/:placeholderB"
+ expectedPath: "http://test.example.io/qux/",
+ },
+ }
+
+ for name, tt := range tests {
+ t.Run(name, func(t *testing.T) {
+ rules, err := netlifyRedirects.ParseString(tt.rule)
+ require.NoError(t, err)
+
+ parsedURL, err := url.Parse(tt.path)
+ require.NoError(t, err)
+
+ isMatch, path := matchesRule(&rules[0], parsedURL)
+ require.Equal(t, tt.expectMatch, isMatch)
+ require.Equal(t, tt.expectedPath, path)
+ })
+ }
+}
+
+// Tests matching behavior when the `FF_ENABLE_DOMAIN_REDIRECT`
+// feature flag is not enabled. These tests can be removed when the
+// `FF_ENABLE_DOMAIN_REDIRECT` flag is removed.
+func Test_matchesDomainRule_DomainRedirect_Disabled(t *testing.T) {
+ t.Setenv(feature.RedirectsPlaceholders.EnvVariable, "true")
+ t.Setenv(feature.DomainRedirects.EnvVariable, "false")
+
+ tests := map[string]testCaseData{
+ "exact_match": {
+ rule: "http://pages.example.io/foo/ http://test.example.io/bar/",
+ path: "http://pages.example.io/foo/",
+ expectMatch: false,
+ expectedPath: "",
+ },
+ }
+
+ for name, tt := range tests {
+ t.Run(name, func(t *testing.T) {
+ rules, err := netlifyRedirects.ParseString(tt.rule)
+ require.NoError(t, err)
+
+ parsedURL, err := url.Parse(tt.path)
+ require.NoError(t, err)
+
+ isMatch, path := matchesRule(&rules[0], parsedURL)
require.Equal(t, tt.expectMatch, isMatch)
require.Equal(t, tt.expectedPath, path)
})