8000 test: clean protocol tests by wooorm-arcjet · Pull Request #4479 · arcjet/arcjet-js · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

test: clean protocol tests #4479

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 17 commits into
base: main
Choose a base branch
from
Open

test: clean protocol tests #4479

wants to merge 17 commits into from

Conversation

wooorm-arcjet
Copy link
Member
@wooorm-arcjet wooorm-arcjet commented Jun 20, 2025

In GH-4415 and GH-4472 I noticed that in particular the protocol tests could use some cleaning up.
I had some extra time to work on a big PR due to holiday in US.

Test cases were often testing equality of big objects as a sort of “fixture” testing. This made it difficult to see what was different between test cases. And, if a property would be added to such objects, all tests would need changing.

After cleaning (the first 2 commits), I went through the uncovered lines and added tests cases for them.

Importantly, there are barely any changes to client.ts and index.ts. Only because their behavior was not tested, and not allowed by the types, I removed the dead code.

Please open the files that GH collapses, and tip: go through commits one by one

@wooorm-arcjet wooorm-arcjet requested a review from a team as a code owner June 20, 2025 12:28
Copy link
trunk-io bot commented Jun 20, 2025

Merging to main in this repository is managed by Trunk.

  • To merge this pull request, check the box to the left or comment /trunk merge below.

@wooorm-arcjet
Copy link
Member Author

Q: The generated BotRule, BotRule_Patterns in the protocol are not called/covered. Is that because those are deprecated v1 things? If they still exist, would it make sense to somehow cover them anyway? How?

@blaine-arcjet
Copy link
Contributor

Q: The generated BotRule, BotRule_Patterns in the protocol are not called/covered. Is that because those are deprecated v1 things? If they still exist, would it make sense to somehow cover them anyway? How?

Yeah, these are in the protobuf files, which is all codegen'd. Those are still in the protobuf because old SDK versions can still submit to our RPC server. I don't believe there is a way to filter them at codegen, but that would be the only place to remove them.

I don't really want them to have tests because that indicates "support" to me.

Copy link
Contributor
@blaine-arcjet blaine-arcjet left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks pretty good, but I had some feedback

// body: details.body,
extra: details.extra,
email: typeof details.email === "string" ? details.email : undefined,
email: details.email,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we want defensive programming around this still.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All the other properties pass things through. Why is email different from extra, query, etc?
Should those then not also get such checks?

Copy link
Contributor
8000

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All properties besides email are provided via an adapter. However, email has to be passed to protect() because it is dynamic content, such as:

const decision = await aj.protect(req, { email: "foobarbaz" })

Since type magic is done for the 2nd argument of protect (required values depending on configured rules), we'd need to do a lot of work to guard around it in adapters. It is just easier to guard this on the string type here and send undefined to the server, where validation will fail if they pass a number or something.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this can be improved in the types then.
It does feel a bit smelly that there is but one such field.
Done.

// body: details.body,
extra: details.extra,
email: typeof details.email === "string" ? details.email : undefined,
email: details.email,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

see above

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

Comment on lines +802 to +804
// TODO(@wooorm-arcjet):
// if it is intentional that people can extend rules,
// then we need to allow that in the types.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is allowed (see https://docs.arcjet.com/blueprints/defining-custom-rules) but is pretty advanced functionality. The types represent it so we have to consider in code that consumes rules.

Copy link
Member Author
@wooorm-arcjet wooorm-arcjet Jun 23, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cool!
It is possible to let users add types. I think that could be used here.
Similar to how TS adds things in more recent JavaScript versions.

As an example: MDX expressions are an extension to markdown. In the AST, they are added with the declare module stuff at the bottom of index.d.ts here: https://www.npmjs.com/package/mdast-util-mdx-expression?activeTab=code. It adds “into” the types at index.d.ts of https://www.npmjs.com/package/@types/mdast?activeTab=code

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not against the idea, but I'd need to see it. I'd rather have simple types than exact types since many users just use JS with no type hinting and saying this can be any string helps code towards that.

Copy link
Member Author
@wooorm-arcjet wooorm-arcjet Jun 24, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am hopeful we can have both

return new DecideResponse({
decision: {
conclusion: Conclusion.ALLOW,
// TODO(@wooorm-arcjet): is it intentional that this is an *empty* rule, not like `rule` at all?
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Welcome to the world of protobuf, where everything is optional and you hate your life 🙃

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Still, on L266, there are all these properties? Shouldn’t some of those fields go into this rule?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

An ArcjetRule and the Rule in the Protobuf are different. An ArcjetRule contains both the local and remote definitions, we use some of the properties to build the remote definition (when convert functions to protobuf). Since all fields in the Protobuf are optional, everything has a "zero" value and the constructor zeros every property—there is no reason to specify zero properties.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

okay, removed the note

assert.equal(calls, 0);
calls++;

// TODO(@wooorm-arcjet): is it intentional that this is an *empty* rule, not like `rule` at all?
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See above

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

removed the note

@blaine-arcjet
Copy link
Contributor

Does this also resolve #32 ?

@wooorm-arcjet
Copy link
Member Author

Does this also resolve #32?

I think so! I think you had a comment similar to that issue in the code, and I solved it, by sort of sidestepping it by inspecting timeoutMs(), which returns the remaining time

@wooorm-arcjet
Copy link
Member Author

I think that’s all the comments!

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.

2 participants
0