Skip to content
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

Improve our approach for testing auth (part 2) - basicAuth #9983

Open
wants to merge 51 commits into
base: master
Choose a base branch
from

Conversation

jNullj
Copy link
Collaborator

@jNullj jNullj commented Feb 22, 2024

This PR is follow-up for #9681 and helps to reach the goal of #9493

This PR will include refactor of all basicAuth services:

Additional changes to authTest:
4d57607 - Add exampleOverride
f156762 - Add authOverride
cd6c65b - Add configOverrid
cf34fae - Split invoke params into path and query
a713669 - Improve error handling, Throw error when service auth key is missing
99a01e1 - Handle case of userKey without passKey
74554d7 - Add option to ignore openApi example in testAuth
8c38355 - Handle auth.defaultToEmptyStringForUser
57163eb - Add support for multiple requests in service

Change auth tests to include all shields of the base class.
The code is formated to be used in more general cases and increases code reuseability.
We already test all existing classes, no need for a dummy
Add getBadgeExampleCall to extract the first OpenAPI example then reformat it for service invoke function.
Add the testAuth function which tests auth of a service (badge) using a provided dummy response.
Add all auth methods used to testAuth to be generic and used by all services.
Add helper functions to make testAuth more readable
Use apiHeaderKey & bearerHeaderKey as function params rather then extracting them with regex from function strings.

Those options are now part of an options object param joined with the contentType that replaces header.

header was originaly added for setting content type of the reply, so it makes more sense to directly set the content type
Before this commit the QueryStringAuth would only work for the key of stackexchange.
This commit makes the testAuth function generic and allows passing user and pass keys.
Might set wrong header for jwt login request.
This commit fixes that.
Some services might have more then one authOrigin.
This commit makes sure we test for redundent authOrigins as well as support requests to them if needed.
Prior to this change, JwtAuth testing would lead to erros due to the absence of a specified login endpoint,
Nock would be dumplicated for both login and non login hosts and indicate a missing request.

This commit enforces the requirement for a new jwtLoginEndpoint argument when testing JwtAuth.
The argument seperates the endpoint nock scope from the behavior of the request nock.
@jNullj jNullj added the javascript Pull requests that update Javascript code label Feb 22, 2024
Some classes can change the auth based on badge inputs.
This parameter allows the flexability of overriding the default auth for testing those cases.
Some tests might require non default config for cases where these are set.
This allows creating tests for those cases.
Splits testAuth example params into path and query params.
Introduce paramType to getBadgeExampleCall
Refactor to add auth static properties.
for better integration with testAuth.

Refactor bitbucketpullrequest for testAuth
@jNullj jNullj force-pushed the feat/9493/improve-auth-testing branch from 1dca6ff to b9d51d1 Compare February 24, 2024 23:20
@jNullj jNullj force-pushed the feat/9493/improve-auth-testing branch from 100e7dc to c6079c5 Compare March 9, 2024 15:41
Enhance reliability by throwing a TypeError when a service key definition is missing.
It's common for a key to be missing and might require the developer that writes tests to provide a fake on that fits the examples used.

Key changes:
- Added a check for missing service key definitions in getServiceClassAuthOrigin.
- Throws a TypeError with a clear message if the key is not found.
- Guides devs to use an override if needed which is often.
Addresses a scenario where generateFakeConfig/testAuth would fail for classes using auth.userKey without auth.passKey.
Ensures proper handling of user-specific authentication even if a password key is not present.
Throws a TypeError only when both fakeKey and fakeUser are missing.
Better fit for AuthHelper behivor.
Added for services without openApi examples.
Dev can use example override to add example inputs in those cases.
@jNullj jNullj force-pushed the feat/9493/improve-auth-testing branch from c6079c5 to 8b8bf19 Compare March 9, 2024 17:16
Some services might have more then one request to auth with the server for the same shield.
This commit adds support for those requests in testAuth using the new multipleRequests option.
Missing return for async mocha tests caused the tests to run async and throw errors of one test in another.
This commit makes sure all testAuth tests return a promise to mocha for it to await.
@jNullj jNullj force-pushed the feat/9493/improve-auth-testing branch from 6a74894 to 1b425aa Compare April 6, 2024 10:55
@jNullj jNullj marked this pull request as ready for review April 6, 2024 11:14
@jNullj
Copy link
Collaborator Author

jNullj commented Apr 6, 2024

This PR is larger then i anticipated, next time i will break down to groups of 1-2 services.

@chris48s
Copy link
Member

chris48s commented Apr 6, 2024

Yeah - this one looks like a bit of a beast.

Just to set expectations, I'm going to be away on holiday all next week so I may not get to reviewing this for a while - we'll see how it goes. It is on my radar though.

Thanks for your continued help with this project :)

@chris48s
Copy link
Member

Hi. Sorry it has taken a while to get back to this.

To start with, I've just been looking at the changes to services/test-helpers.js.
Tbh, I'm a bit worried by the number of slight variants we're introducing into the helper code here.

Here's a question for you:
How many of the services touched in this PR could have been converted to use testAuth() without adding extra optional params in services/test-helpers.js, or is there a subset we could have added with only minimal changes?

I'm not sure I have all the answers, but if every service (or nearly every) service we want to test means we have to add some new optional param to the test helper function to test it, I think that is telling us that we're zeroing in on the wrong abstraction here.

@jNullj
Copy link
Collaborator Author

jNullj commented May 3, 2024

Hi. Sorry it has taken a while to get back to this.

To start with, I've just been looking at the changes to services/test-helpers.js. Tbh, I'm a bit worried by the number of slight variants we're introducing into the helper code here.

Here's a question for you: How many of the services touched in this PR could have been converted to use testAuth() without adding extra optional params in services/test-helpers.js, or is there a subset we could have added with only minimal changes?

I'm not sure I have all the answers, but if every service (or nearly every) service we want to test means we have to add some new optional param to the test helper function to test it, I think that is telling us that we're zeroing in on the wrong abstraction here.

For scale, in this PR i updated tests of 8 services to use testAuth() with a total of 25 tests.
I mapped each new test and special options used other then service-class, auth method and dummy-response.
image

Some insight:

  1. Config override is the most used option, this is relevant for all services with an option (or even a required) server url. To test these services we must set the authOrigin in config for the test, but while i could try to add the detection for needing to use config-override in those cases automatically, i cant think of a robust way of detecting which service class requires that. For example while most services in this pr uses server query param jira uses jobUrl, so i think that using the server openapi param might result in issues. I could still attempt to make those changes if you think its better to avoid additional options required by the dev, with the higher risk of having issues once in a service.
  2. Regarding content-type i think i could remove that option by using getPrototypeOf() or introducing a new type property to the BaseService class and set it values in each class type to hint at the response header required, let me know which of these sounds like the better options, i think using getPrototypeOf is harder to understand for someone new to that code, but comes with the benefit of not effecting production code (less memory as we dont add new property).
  3. ignoreOpenApiExample is used due to non-existing openapi example for the tested class, in this case this is expected as its a parent of the services. We could use it every time openapi example is missing but that would lead to confusion imo as the dev writing the test won't easily know why his text misbehaves. I think its better to keep it an intentional option to both signal the dev this example is unique and to force the dev to understand the crafted new test should be unique. I think its better if we think of a good way to document that properly.
  4. Multiple outputs - cant think of a way to automate this, i think if we had a way it would be better then an option. It's relevant to any service that uses more then one request.
  5. auth override - testAuth is extracting the auth params from the service class auth property, but bitbucket is unique and uses 2 properties. This is a unique class and i doubt we be required to do that often, let me know what do you think we could do with that one?
  6. example override - Required every time openapi is ignored, the second and more common use case is for issues with openapi example.
    6.1. AzureDevOpsTests & JenkinsTests - used to bypass issue with compact_message
    6.2. BitbucketRawPullRequests - openapi example is to use hosted server, but we also want to test code branch of cloud host.
    6.3. SonarGeneric - used due to ignoreOpenApiExample (missing open api example)
    6.4. SonarViolations - openapi example uses the less common use case so an override is used to test the common case

Should we focus on another iteration where we try to reduce some options i mentioned above or should we focus more on new ways to tackle the larger issue?

Its hard to tell if we will see many more options used in the tests not yet converted or not before attempting to add those tests.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
core Server, BaseService, GitHub auth developer-experience Dev tooling, test framework, and CI javascript Pull requests that update Javascript code
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants