mirror of
https://github.com/PrivateCaptcha/PrivateCaptcha.git
synced 2026-02-12 08:50:28 -06:00
Fix tests
This commit is contained in:
@@ -29,3 +29,5 @@ func (sm *stubMetrics) ObservePuzzleVerified(userID int32, result string, isStub
|
||||
|
||||
func (sm *stubMetrics) ObserveHealth(postgres, clickhouse bool) {}
|
||||
func (sm *stubMetrics) ObserveCacheHitRatio(ratio float64) {}
|
||||
|
||||
func (sm *stubMetrics) ObserveHttpError(handlerID string, method string, code int) {}
|
||||
|
||||
@@ -11,6 +11,7 @@ import (
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"net/url"
|
||||
"regexp"
|
||||
"slices"
|
||||
"strconv"
|
||||
"strings"
|
||||
@@ -44,9 +45,38 @@ func (f *StubPuzzleEngine) Verify(ctx context.Context, payload puzzle.SolutionPa
|
||||
return f.Result, nil
|
||||
}
|
||||
|
||||
func wrapScriptContentsWithCDATA(input []byte) []byte {
|
||||
re := regexp.MustCompile(`(?s)(<script[^>]*>)(.*?)(</script>)`)
|
||||
|
||||
return re.ReplaceAllFunc(input, func(match []byte) []byte {
|
||||
parts := re.FindSubmatch(match)
|
||||
if len(parts) != 4 {
|
||||
return match // safety fallback
|
||||
}
|
||||
openTag := parts[1]
|
||||
content := parts[2]
|
||||
closeTag := parts[3]
|
||||
|
||||
// Skip if already wrapped in CDATA
|
||||
if bytes.Contains(content, []byte("<![CDATA[")) {
|
||||
return match
|
||||
}
|
||||
|
||||
var buf bytes.Buffer
|
||||
buf.Write(openTag)
|
||||
buf.WriteString("<![CDATA[")
|
||||
buf.Write(content)
|
||||
buf.WriteString("]]>")
|
||||
buf.Write(closeTag)
|
||||
return buf.Bytes()
|
||||
})
|
||||
}
|
||||
|
||||
// courtesy of https://martinfowler.com/articles/tdd-html-templates.html
|
||||
func AssertWellFormedHTML(t *testing.T, buf bytes.Buffer) {
|
||||
data := buf.Bytes()
|
||||
// '<=' (e.g. in for loops) in <script> breaks XML parser
|
||||
data = wrapScriptContentsWithCDATA(data)
|
||||
// special handling for Alpine.js, otherwise we get XML parsing error "attribute expected"
|
||||
data = bytes.ReplaceAll(data, []byte(" @click="), []byte(" click="))
|
||||
data = bytes.ReplaceAll(data, []byte(" hx-on::"), []byte(" hx-on-"))
|
||||
|
||||
@@ -12,8 +12,7 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
twofactorFormTemplate = ""
|
||||
twofactorTemplate = "twofactor/twofactor.html"
|
||||
twofactorTemplate = "twofactor/twofactor.html"
|
||||
)
|
||||
|
||||
var (
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
|
||||
<div class="relative flex items-center mt-4" x-data="resendTimer()">
|
||||
<div class="text-base" hx-target="this" hx-swap="innerHTML">
|
||||
<p class="pc-form-text">{{ if .Params.Error }}<span class="pc-form-text-error">{{.Params.Error}}</span>{{ else }}Did not receive the code?{{ end }} <a hx-post='{{ relURL .Const.ResendEndpoint }}' href="#" title="" class="pc-form-link" x-bind:class="{ 'opacity-50 pointer-events-none': !canResend }" x-text="canResend ? 'Resend' : `Resend (${countdown}s)`">Resend</a></p>
|
||||
<p class="pc-form-text">{{ if .Params.Error }}<span class="pc-form-text-error">{{.Params.Error}}</span>{{ else }}Did not receive the code?{{ end }} <a hx-post='{{ relURL .Const.ResendEndpoint }}' href="#" title="" class="pc-form-link" :class="{ 'opacity-50 pointer-events-none': !canResend }" x-text="canResend ? 'Resend' : `Resend (${countdown}s)`">Resend</a></p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user