Skip to content

test(middleware): add testify suite for DecompressRequestMiddleware - #1

Closed
xiaoyuyu6420 wants to merge 431 commits into
nerimoe:mainfrom
xiaoyuyu6420:contrib/zstd-tests-for-4936
Closed

test(middleware): add testify suite for DecompressRequestMiddleware#1
xiaoyuyu6420 wants to merge 431 commits into
nerimoe:mainfrom
xiaoyuyu6420:contrib/zstd-tests-for-4936

Conversation

@xiaoyuyu6420

Copy link
Copy Markdown

Hi @nerimoe,

Following up on our conversation in #4936 — here is the testify test suite, contributed to your branch as you suggested.

What this adds

15 testify tests covering all behaviour in QuantumNous#4936, all passing against the gzip.go in your main branch (verified locally):

Test What it covers
Zstd The core regression from QuantumNous#6313
AllEncodingsBehaviorParity gzip/br/zstd all decode + strip header identically
UncompressedPassThrough No Content-Encoding → body untouched
InvalidZstdDoesNotLeak Malformed zstd does not leak raw bytes to JSON parser
GetSkipped GET requests are not touched
ZstdProducesValidJSON End-to-end: decompressed body unmarshals via common.Unmarshal
PeekDetectsGzipWithoutHeader Magic-byte peek detects gzip without Content-Encoding
PeekDetectsZstdWithoutHeader Magic-byte peek detects zstd without Content-Encoding
IdentityEncodingPassesThrough Content-Encoding: identity passes through unchanged
UnsupportedEncodingReturns415 deflate etc. → 415 with OpenAI-style JSON
InvalidGzipReturns400 Invalid gzip → 400 with structured JSON error
ContentLengthClearedAfterDecompression Content-Length/-header removed for gzip/br/zstd
PeekDetectsGzipWithIdentityHeader Peek works even under explicit identity header
EmptyBodyNoEncoding Empty body + no encoding handled without error

All tests use testify (require/assert) per AGENTS.md, and common.Unmarshal/common.Marshal instead of encoding/json.

Once you merge this, I will close QuantumNous#6348 in favor of QuantumNous#4936. 🚀

Calcium-Ion and others added 30 commits June 19, 2026 15:10
* refactor: codex usage ui

* feat: show Codex reset credit details

* feat: add Codex usage reset flow
Add an opt-in card view to the shared data-table stack (DataTablePage),
toggled via a segmented control in the toolbar with per-table localStorage
persistence. Cards render generically from column meta by default, with an
optional renderCard slot. Defaults to table-only so existing pages are
unchanged.

Wire it into the channels page with a bespoke ChannelCard that reuses every
column's cell renderer, preserving all table information and interactions
(selection, inline priority/weight, balance refresh, status, actions, tag
expand).
Group #id/name and balance on the left and priority/weight plus
response/last-tested on the right. Simplify field labels by dropping
the CJK-unfriendly uppercase/letter-spacing, left-align the right
column, and shorten the "Last Tested" zh label.
- Show 3-column card grid from xl breakpoint instead of 2xl
- Cap inline priority/weight width to avoid huge values stretching cards
- Collapse right-column grid to content-sized columns, removing wasted space
- Memoize channel columns, context value, upstream-update result, and ChannelCard
  to avoid rebuilding/re-rendering all cards on unrelated state changes
* feat(dashboard): add traffic flow sankey chart

Add dashboard flow APIs and a Sankey-based flow view with user, optional API key, model, and channel layers.\n\nReuse the dashboard VChart palette, add precise link/node tooltips and interactions, and cover filtering, layer ordering, color stability, and error states with tests.

* feat: build flow chart from quota data

---------

Co-authored-by: CaIon <i@caion.me>
路由 search 校验枚举 logTypeValues 漏了 '7'(登录),
选「登录」时 type=['7'] 校验失败被 .catch([]) 兜底成空数组,
最终请求丢掉 type 参数。补上 '7' 与 LOG_TYPE_ENUM.LOGIN 对齐。
base-ui 的 ScrollArea 仅靠 max-height 无法约束高度:其 Viewport 用
height:100%,当 Root 只有 max-height 而无确定高度时会回退为 auto,
内容撑满并溢出到 Root 之外,盖住下方分页。改用原生 max-h + overflow-y-auto
的 div,列表正确内部滚动,分页作为同级元素干净地排在下方。
删除时已从草稿中移除模型,但列表为 saved∪draft 并集且优先取 saved,
导致行不消失(isDraftDeleted 计算后未被使用),表现为无法删除。改为过滤
掉已暂存删除的行;并在删除当前正在编辑的行时关闭编辑器,避免从残留面板
保存又把模型写回。
- Highlight full paths through a clicked node or link in the flow Sankey,
  dimming unrelated nodes/links instead of removing them
- Disable VChart built-in emphasis to avoid crash, use custom highlight sets
- Initialize models filter dialog from currently applied filters so manual
  time ranges are not overridden by preferences; auto-pick granularity by range
- Lift user charts time range/granularity/limit to dashboard as controlled state
Add an eye toggle in the flow section header that masks sensitive node
labels (users, tokens, nodes, groups, channels) in the Sankey while keeping
model names visible. Masking only rewrites display text; nodes stay distinct
via their key so graph structure, links, and highlighting are unaffected.
…c frontend) (QuantumNous#5631)

resolveModelProvider in model-badge.tsx only covered mainstream providers
(OpenAI/Claude/Gemini/Grok/DeepSeek/Qwen/Doubao/Moonshot/Mistral/Meta/Cohere).
Models from Zhipu (glm-), MiniMax, Xiaomi MiMo, Baidu (ernie), iFlyTek
(spark), Tencent (hunyuan), Baichuan, InternLM, StepFun, and Yi rendered
as grey dots instead of their brand icons in the usage logs table.

Add keyword mappings for these providers, aligning coverage with the
classic frontend's getModelCategories. Icons resolved via @lobehub/icons.
* feat: add passive channel monitoring mode

* fix: clarify passive monitor mode copy
…#5659)

Fall back to the OS hostname when NODE_NAME is not configured, so node
identity in audit/usage logs is populated automatically. In container and
Kubernetes deployments the hostname equals the container ID or Pod name,
which stays unique under autoscaling without any manual per-instance config.
* feat: support ClickHouse log database

* feat(log): optimize log deletion process for ClickHouse
feitianbubu and others added 26 commits July 26, 2026 14:46
…lling

Add admin-configurable tool-call prices with cross-provider surcharge
settlement, Sub2API channel support, /v1/alpha/search relay, and usage-log
surcharge UI.
…module (QuantumNous#6369)

* test(relayconvert): add golden snapshot matrix and relaykit boundary guard

Phase 0 of the relaykit extraction plan: pin byte-level output of every
registered (from,to) request/response/stream conversion route, and
forbid kit-bound packages from growing host-only imports.

* wip(relayconvert): drop gin.Context from converter signatures; add convmeta draft

Phase 1 in progress: relayconvert now takes context.Context; host media
resolver adapts gin.Context back at the service boundary.

* refactor(relayconvert): decouple converters from RelayInfo, gin, and settings

Phase 1 of the relaykit extraction plan:
- converters now depend on convmeta.Meta (implemented by RelayInfo) instead
  of *relaycommon.RelayInfo; ClaudeConvertInfo and the format guesser move
  to convmeta with aliases left behind
- host settings reach converters via a convmeta.Options snapshot built in
  RelayInfo.ConvOptions; no more model_setting/reasoning global reads inside
  the conversion layer
- effort-suffix helpers move to service/relayconvert/reasoning (old package
  forwards); chat-to-responses upgrade policy moves to service (host routing
  logic, not conversion)
- golden conversion matrix unchanged

* test(relayconvert): tighten boundary — kit packages now free of gin/setting imports

* refactor(dto): drop gin and logger dependencies

Phase 2 (part 1): dto.Request.IsStream now takes *http.Request instead of
*gin.Context (Gemini's impl reads query/path off the std request); dto's
three logger calls become common.SysError. Boundary test allowlist is now
empty — kit-bound packages import no gin/setting/logger/model.

* refactor(kit): extract dependency-free kitutil; dto/types/relayconvert stop importing common

Phase 2 of the relaykit extraction plan:
- new service/relayconvert/kitutil holds the pure helpers the kit needs
  (JSON wrappers, pointer/string/uuid/timestamp utils, MaskSensitiveInfo,
  pluggable LogInfo/LogError hooks, Debug flag)
- dto, types, and all relayconvert packages now use kitutil; their only
  remaining internal deps are dto/types/constant
- common keeps every original symbol (MaskSensitiveInfo delegates to
  kitutil) so host code is untouched; main.go routes kit logging into
  common.SysLog/SysError and mirrors DebugEnabled
- golden conversion matrix unchanged

* refactor(kit): move EndpointType/FinishReason to types; OpenRouter dialect via Options

Kit packages (dto/types/relayconvert/reasonmap) no longer import constant:
- EndpointType and finish-reason values live in types; constant re-exports
- the OpenRouter special-case in claude->openai request conversion reads
  Options.OpenRouterDialect, set by the host from the channel type;
  InitChannelMeta invalidates the cached snapshot on channel switch

* refactor: extract relaykit submodule (dto/types/relayconvert/reasonmap)

Phase 3 of the relaykit extraction plan:
- new go module github.com/QuantumNous/new-api/relaykit containing dto
  (minus task family), types, relayconvert (with convmeta/kitutil/reasoning),
  and reasonmap; host consumes it via require + replace, go.work for dev
- task-family dto (task/suno/midjourney/video) stays in the host dto
  package; dual-consumer host files alias it as taskdto
- relaykit builds and tests standalone (GOWORK=off): no host imports,
  no gin, no DB, no settings
- golden conversion matrix unchanged

* build(docker): copy relaykit/go.mod before go mod download

The local-replace submodule's go.mod must exist inside the build context
for the main module graph to resolve.

* fix: address relaykit extraction regressions

* fix: address relaykit review regressions

* docs: document Meta nil receiver contract

* fix(relaykit): fail OpenAI→Claude conversion without max_tokens; reject negative default_max_tokens

The Claude Messages API requires max_tokens (omitting it is a 400
"Field required"), but with a nil Options.Claude.DefaultMaxTokens hook
the converters silently emitted a request the upstream is guaranteed to
reject. Both OpenAI Chat and Responses → Claude conversions now return
sharedclaude.ErrMissingMaxTokens when no path (client value, default
hook, thinking-adapter floor) supplied one. Unreachable in the host,
which always configures the hook.

Host side, claude.default_max_tokens now rejects negative values at the
option API before persisting — they would wrap into huge unsigned values
during conversion. Zero stays allowed: the current API treats
max_tokens: 0 as cache pre-warming.

* fix: make Gemini safety settings read path race-free
* fix: parameterize slow/error SQL logs to avoid leaking credentials

* fix: validate SQL_SLOW_THRESHOLD_MS range

* fix: sanitize database driver error messages in SQL logs

* refactor: sanitize at gorm log writer seam to keep caller attribution
* docs: add design spec for OIDC custom display name

Mirrors the existing Custom OAuth Provider name pattern so admins can
show a meaningful label instead of the hardcoded "OIDC" on the login
page and in related copy.

* feat(oidc): add configurable display name with OIDC fallback

* feat(oidc): use configured display name in provider name and status API

* feat(oidc): add display name field to default-theme OIDC settings

Claude-Session: https://claude.ai/code/session_01FDkWJqigJi9yE3HG5pjZP5

* feat(oidc): show configured display name on default-theme login button

* feat(oidc): add display name field to classic-theme OIDC settings

* feat(oidc): show configured display name on classic-theme login button

* fix(oidc): trim whitespace before applying display name fallback

* chore: remove internal design doc from PR

Design/planning docs are working artifacts for this session and
shouldn't be submitted to the upstream project.

* fix(oidc): lead with example in classic-theme display name placeholder

Reorders the combined placeholder to show the example first, then
the fallback note, matching the Custom OAuth Provider Name field's
placeholder convention (example-only) that this feature mirrors.

* fix(i18n): improve Russian grammar in OIDC display-name placeholder translation

Leads each clause with its condition/subject and adds the missing
verb, per PR review feedback.

* test(web): remove redundant OIDC harness tests
* fix: preserve qwen thinking budget

* test: address qwen thinking budget review comments

* chore: remove unreachable adaptor code

* test: cover zero Qwen thinking budgets
Adds 15 testify tests covering all behaviour in QuantumNous#4936:
- Zstd regression (QuantumNous#6313), encoding parity (gzip/br/zstd)
- Peek auto-detection without Content-Encoding header (gzip + zstd)
- Peek with Content-Encoding: identity (gzip detected under identity)
- 415 for unsupported encodings (e.g. deflate) with OpenAI-style JSON
- 400 for invalid gzip with structured JSON error
- Content-Length cleanup after decompression (gzip/br/zstd)
- Identity passthrough, GET skip, empty body, invalid zstd no-leak
- End-to-end JSON unmarshal via common.Unmarshal

All 15 tests pass against the current gzip.go in this branch.
@xiaoyuyu6420

Copy link
Copy Markdown
Author

QuantumNous#4936 已经被 maintainer (seefs001) 关闭,他自己写了 QuantumNous#6545 合进主线了。这个测试 PR 挂在这里没意义了,关掉。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.