Repository: OptimalBits/bull (JavaScript)

Issue:
[Bug] constructor with options does not destructure redis property if it is a string
<!--
You may report several types of issues. Bug reports, enhancements or questions.
For bug reports however you are required to provide some information so that the 
issue can be resolved efficiently. The following template should be filled for bugs.

Before submitting the bug just think twice if you really need to submit the bug
or you may have some issue in your own code, remember that handling issues is
time consuming, would you better like that we spend time improving the library
or on non-issues :).
-->

## Description

When passing redis connection as options object but it is a url, the url will not destructed

https://github.com/OptimalBits/bull/blob/4d197e81771df115d6af3f2d66b3797ed680d97c/lib/queue.js#L85-L129

If not passed as string, the `if` in line 90 will be omitted and then it be ignored via line 129 because this takes precedents over string

## Minimal, Working Test code to reproduce the issue.

```ts
import Queue from 'bull';

new Queue<any>('name', { redis: 'redis://my.host/6379' }); // results in 127.0.0.1 ❌

new Queue<any>('name', 'redis://my.host/6379'); // results in my.host ✅
```

## Bull version

4.11.3

## Additional information

This took me around 4h to find out...


Discussion:
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

Please only mark issues and PRs as stale if there are reasons why e.g. they couldn't get reviewed or merged.
This behavior of marking issues as stale is not helping anyone.
:tada: This issue has been resolved in version 4.11.5 :tada:

The release is available on:
- [npm package (@latest dist-tag)](https://www.npmjs.com/package/bull/v/4.11.5)
- [GitHub release](https://github.com/OptimalBits/bull/releases/tag/v4.11.5)

Your **[semantic-release](https://github.com/semantic-release/semantic-release)** bot :package::rocket:



Patch:
diff --git a/lib/queue.js b/lib/queue.js
index 2afc8b543..d8a0f31cd 100755
--- a/lib/queue.js
+++ b/lib/queue.js
@@ -121,7 +121,9 @@ const Queue = function Queue(name, url, opts) {
 
   opts.redis = {
     enableReadyCheck: false,
-    ...opts.redis
+    ...(_.isString(opts.redis)
+      ? { ...redisOptsFromUrl(opts.redis) }
+      : opts.redis)
   };
 
   _.defaults(opts.redis, {
@@ -913,7 +915,7 @@ Queue.prototype.isPaused = async function(isLocal) {
 };
 
 Queue.prototype.run = function(concurrency, handlerName) {
-  if(!Number.isInteger(concurrency)) {
+  if (!Number.isInteger(concurrency)) {
     throw new Error('Cannot set Float as concurrency');
   }
   const promises = [];


Test patch:
diff --git a/test/test_child-pool.js b/test/test_child-pool.js
index b5b09ef25..e75831906 100644
--- a/test/test_child-pool.js
+++ b/test/test_child-pool.js
@@ -151,12 +151,12 @@ describe('Child pool', () => {
   });
 
   it('should not overwrite the the childPool singleton when isSharedChildPool is false', () => {
-    const childPoolA = new childPool(true)
-    const childPoolB = new childPool(false)
+    const childPoolA = new childPool(true);
+    const childPoolB = new childPool(false);
     const childPoolC = new childPool(true);
 
-    expect(childPoolA).to.be.equal(childPoolC)
-    expect(childPoolB).to.not.be.equal(childPoolA)
-    expect(childPoolB).to.not.be.equal(childPoolC)
-  })
+    expect(childPoolA).to.be.equal(childPoolC);
+    expect(childPoolB).to.not.be.equal(childPoolA);
+    expect(childPoolB).to.not.be.equal(childPoolC);
+  });
 });
diff --git a/test/test_queue.js b/test/test_queue.js
index b7693262c..22061fb22 100644
--- a/test/test_queue.js
+++ b/test/test_queue.js
@@ -206,6 +206,23 @@ describe('Queue', () => {
       return queue.close();
     });
 
+    it('creates a queue using the supplied redis url as opts', () => {
+      const queue = new Queue('custom', {
+        redis: 'redis://abc:123@127.2.3.4:1234/1'
+      });
+
+      expect(queue.client.options.host).to.be.eql('127.2.3.4');
+      expect(queue.eclient.options.host).to.be.eql('127.2.3.4');
+
+      expect(queue.client.options.port).to.be.eql(1234);
+      expect(queue.eclient.options.port).to.be.eql(1234);
+
+      expect(queue.client.options.db).to.be.eql(1);
+      expect(queue.eclient.options.db).to.be.eql(1);
+
+      return queue.close();
+    });
+
     it('creates a queue using the supplied redis host', () => {
       const queue = new Queue('custom', { redis: { host: 'localhost' } });