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

fix: updated combine url fix method #1647

Merged
merged 2 commits into from
Jan 8, 2020

Conversation

Grabauskas
Copy link
Member

Type: bug

Added more unit test cases and fixed combineBaseUrl method.
RegExp was changed to slice for optimization.

@Grabauskas Grabauskas changed the title Combine url fix fix: updated combine url fix method Jan 7, 2020
@codecov
Copy link

codecov bot commented Jan 7, 2020

Codecov Report

Merging #1647 into master will increase coverage by 0.02%.
The diff coverage is 100%.

@@            Coverage Diff             @@
##           master    #1647      +/-   ##
==========================================
+ Coverage   84.86%   84.88%   +0.02%     
==========================================
  Files          47       47              
  Lines        2477     2481       +4     
  Branches      579      580       +1     
==========================================
+ Hits         2102     2106       +4     
  Misses        370      370              
  Partials        5        5
Impacted Files Coverage Δ
src/lib/utils.ts 93.98% <100%> (+0.13%) ⬆️

src/lib/utils.ts Outdated
@@ -143,10 +143,13 @@ export function validateMetadata(object: Package, name: string): Package {
export function combineBaseUrl(protocol: string, host: string | void, prefix?: string | void): string {
let result = `${protocol}://${host}`;

if (prefix) {
prefix = prefix.replace(/\/$/, '');
if (prefix && prefix.length !== 0) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
if (prefix && prefix.length !== 0) {
if (prefix && prefix.length) {

Copy link
Member Author

Choose a reason for hiding this comment

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

Already tried that:

Prefer using an optional chain expression instead, as it's more concise and easier to read.eslint(@typescript-eslint/prefer-optional-chain)

Copy link
Member Author

@Grabauskas Grabauskas Jan 7, 2020

Choose a reason for hiding this comment

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

What's the point of prefix property type void?

Because that's why I can't use the optional chain operator:

if (prefix?.length) {

Copy link
Member

Choose a reason for hiding this comment

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

Why not _.isString()? We have used lodash all over the place anyway, also @DanielRuf says is not a critical code, it is called once in a time.

@DanielRuf
Copy link
Contributor

Hi @Grabauskas,

thanks for your PR.

What exactly does this fix? Can you show a failing example or the relevant issue?

@DanielRuf
Copy link
Contributor

Ah ok I see. One case that is fixed now.

Let me check if this can be simplified.
Performance is not critical here.

Summary of all failing tests
 FAIL  test/unit/modules/utils/utils.spec.ts
  ● Utilities › API utilities › combineBaseUrl › should create a base url for registry

    expect(received).toEqual(expected) // deep equality

    Expected: "http://domain"
    Received: ""

      214 |       test('should create a base url for registry', () => {
      215 |         expect(combineBaseUrl("http", 'domain', '')).toEqual('http://domain');
    > 216 |         expect(combineBaseUrl("http", 'domain', '/')).toEqual('http://domain');
          |                                                       ^
      217 |         expect(combineBaseUrl("http", 'domain', '/prefix/')).toEqual('http://domain/prefix');
      218 |         expect(combineBaseUrl("http", 'domain', '/prefix/deep')).toEqual('http://domain/prefix/deep');
      219 |         expect(combineBaseUrl("http", 'domain', 'only-prefix')).toEqual('only-prefix');

      at Object.toEqual (test/unit/modules/utils/utils.spec.ts:216:55)

@DanielRuf
Copy link
Contributor

DanielRuf commented Jan 7, 2020

I would propose the following Return Early Pattern based approach:

export function combineBaseUrl(protocol: string, host: string | void, prefix?: string | void): string {
  let result = `${protocol}://${host}`;

  const prefixOnlySlash = prefix === '/';

  if (prefix && !prefixOnlySlash) {
    if (prefix.endsWith('/')) {
      prefix = prefix.slice(0, -1);
    }

    if (prefix.startsWith('/')) {
      return `${result}${prefix}`;
    }

    return prefix;
  }

  return result;
}

https://www.freecodecamp.org/forum/t/the-return-early-pattern-explained-with-javascript-examples/19364

Opinions @verdaccio/collaborators @verdaccio/core-team

@Grabauskas
Copy link
Member Author

One more test can be added to check if triming is applied.

expect(combineBaseUrl("http", 'domain', ' ')).toEqual('http://domain');

@DanielRuf
Copy link
Contributor

One more test can be added to check if triming is applied.

I don't know if this is a valid or common usecase.

src/lib/utils.ts Outdated

result = prefix.indexOf('/') === 0 ? `${result}${prefix}` : prefix;
result = prefix.length === 0 || prefix.indexOf('/') === 0 ? `${result}${prefix}` : prefix;
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
result = prefix.length === 0 || prefix.indexOf('/') === 0 ? `${result}${prefix}` : prefix;
result = prefix.length === 0 || prefix.startsWith('/') ? `${result}${prefix}` : prefix;

Copy link
Contributor

Choose a reason for hiding this comment

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

All too complicated, also ternary operators are not great to read. See my proposed alternative solution.

#1647 (comment)

@juanpicado
Copy link
Member

I would propose the following Return Early Pattern based approach:

export function combineBaseUrl(protocol: string, host: string | void, prefix?: string | void): string {
  let result = `${protocol}://${host}`;

  const prefixOnlySlash = prefix === '/';

  if (prefix && !prefixOnlySlash) {
    if (prefix.endsWith('/')) {
      prefix = prefix.slice(0, -1);
    }

    if(prefix.indexOf('/') === 0) {
      return `${result}${prefix}`;
    }

    return prefix;
  }

  return result;
}

https://www.freecodecamp.org/forum/t/the-return-early-pattern-explained-with-javascript-examples/19364

Opinions @verdaccio/collaborators @verdaccio/core-team

Much easier to read, I like it.

@juanpicado
Copy link
Member

juanpicado commented Jan 7, 2020

One more test can be added to check if triming is applied.

I don't know if this is a valid or common usecase.

We can trim in the one single place we use this function, I think the job of the method is combineBaseUrl rather clean up / formatting the input .

@DanielRuf
Copy link
Contributor

DanielRuf commented Jan 7, 2020

We can trim in the one single place we use this function, I think the job of the is combineBaseUrl rather clean up / formatting the input .

Agreed 👍

@Grabauskas
Copy link
Member Author

Updated by @DanielRuf solution.

expect(combineBaseUrl("http", 'domain', '/prefix/')).toEqual('http://domain/prefix');
expect(combineBaseUrl("http", 'domain', '/prefix/deep')).toEqual('http://domain/prefix/deep');
expect(combineBaseUrl("http", 'domain', 'only-prefix')).toEqual('only-prefix');
Copy link
Member

Choose a reason for hiding this comment

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

expect(combineBaseUrl("http", 'domain', 'only-prefix')).toEqual('only-prefix');

🤔 ... this outcome is odd ... (not related with this PR but called my attention)

Copy link
Member Author

Choose a reason for hiding this comment

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

In some cases url_prefix can be used as domain.
#622 (comment)

Copy link
Member

Choose a reason for hiding this comment

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

Thank u that makes totally sense .. then I would update the scenario with a real domain, a single string is a bit misleading.

Copy link
Contributor

Choose a reason for hiding this comment

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

Will one of you create anew PR or issue for that?

Copy link
Member

@juanpicado juanpicado left a comment

Choose a reason for hiding this comment

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

Thanks @Grabauskas nice catch ! 👏

@juanpicado juanpicado merged commit 4f43347 into verdaccio:master Jan 8, 2020
@Grabauskas Grabauskas deleted the combine-url-fix branch January 8, 2020 13:37
@Grabauskas Grabauskas restored the combine-url-fix branch January 8, 2020 13:38
@juanpicado juanpicado added this to In progress in Verdaccio Board (future release) via automation Jan 8, 2020
@juanpicado juanpicado moved this from In progress to Done in Verdaccio Board (future release) Jan 8, 2020
@lock
Copy link

lock bot commented Jan 18, 2020

🤖This thread has been automatically locked 🔒 since there has not been any recent activity after it was closed.
We lock tickets after 90 days with the idea to encourage you to open a ticket with new fresh data and to provide you better feedback 🤝and better visibility 👀.
If you consider, you can attach this ticket 📨 to the new one as a reference for better context.
Thanks for being a part of the Verdaccio community! 💘

@lock lock bot locked as resolved and limited conversation to collaborators Jan 18, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants