diff --git a/.gitignore b/.gitignore
index 2773be5d3..e82e8f786 100644
--- a/.gitignore
+++ b/.gitignore
@@ -11,3 +11,4 @@ working.png
ruby/.rails5-gems
web/.rails5-gems
websocket-gateway/.rails5-gems
+.pg_data/
diff --git a/jam-ui/.python-version b/jam-ui/.python-version
new file mode 100644
index 000000000..a61649269
--- /dev/null
+++ b/jam-ui/.python-version
@@ -0,0 +1 @@
+2.7.18
diff --git a/jam-ui/cypress.config.js b/jam-ui/cypress.config.js
new file mode 100644
index 000000000..999a37a56
--- /dev/null
+++ b/jam-ui/cypress.config.js
@@ -0,0 +1,22 @@
+module.exports = {
+ env: {
+ legacyBaseUrl: "http://www.jamkazam.local:3000",
+ apiBaseUrl: "http://www.jamkazam.local:3000/api",
+ },
+
+ e2e: {
+ // We've imported your old cypress plugins here.
+ // You may want to clean this up later by importing these.
+ setupNodeEvents(on, config) {
+ return require("./cypress/plugins/index.js")(on, config);
+ },
+ baseUrl: "http://beta.jamkazam.local:4000",
+ },
+
+ component: {
+ devServer: {
+ framework: "react",
+ bundler: "webpack",
+ },
+ },
+};
diff --git a/jam-ui/cypress.json b/jam-ui/cypress.json
deleted file mode 100644
index 4a1e6b4ef..000000000
--- a/jam-ui/cypress.json
+++ /dev/null
@@ -1,7 +0,0 @@
-{
- "baseUrl": "http://beta.jamkazam.local:4000",
- "env": {
- "legacyBaseUrl": "http://www.jamkazam.local:3000",
- "apiBaseUrl": "http://www.jamkazam.local:3000/api"
- }
-}
diff --git a/jam-ui/cypress/integration/auth/login.js b/jam-ui/cypress/e2e/auth/login.cy.js
similarity index 100%
rename from jam-ui/cypress/integration/auth/login.js
rename to jam-ui/cypress/e2e/auth/login.cy.js
diff --git a/jam-ui/cypress/integration/friends/friends-page.spec.js b/jam-ui/cypress/e2e/friends/friends-page.cy.js
similarity index 100%
rename from jam-ui/cypress/integration/friends/friends-page.spec.js
rename to jam-ui/cypress/e2e/friends/friends-page.cy.js
diff --git a/jam-ui/cypress/integration/layout/navigation.spec.js b/jam-ui/cypress/e2e/layout/navigation.cy.js
similarity index 100%
rename from jam-ui/cypress/integration/layout/navigation.spec.js
rename to jam-ui/cypress/e2e/layout/navigation.cy.js
diff --git a/jam-ui/cypress/support/component-index.html b/jam-ui/cypress/support/component-index.html
new file mode 100644
index 000000000..ac6e79fd8
--- /dev/null
+++ b/jam-ui/cypress/support/component-index.html
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+ Components App
+
+
+
+
+
\ No newline at end of file
diff --git a/jam-ui/cypress/support/component.js b/jam-ui/cypress/support/component.js
new file mode 100644
index 000000000..0d9eef905
--- /dev/null
+++ b/jam-ui/cypress/support/component.js
@@ -0,0 +1,27 @@
+// ***********************************************************
+// This example support/component.js is processed and
+// loaded automatically before your test files.
+//
+// This is a great place to put global configuration and
+// behavior that modifies Cypress.
+//
+// You can change the location of this file or turn off
+// automatically serving support files with the
+// 'supportFile' configuration option.
+//
+// You can read more here:
+// https://on.cypress.io/configuration
+// ***********************************************************
+
+// Import commands.js using ES2015 syntax:
+import './commands'
+
+// Alternatively you can use CommonJS syntax:
+// require('./commands')
+
+import { mount } from 'cypress/react'
+
+Cypress.Commands.add('mount', mount)
+
+// Example use:
+// cy.mount()
\ No newline at end of file
diff --git a/jam-ui/cypress/support/index.js b/jam-ui/cypress/support/e2e.js
similarity index 100%
rename from jam-ui/cypress/support/index.js
rename to jam-ui/cypress/support/e2e.js
diff --git a/jam-ui/package-lock.json b/jam-ui/package-lock.json
index c38b0b51f..172964b85 100644
--- a/jam-ui/package-lock.json
+++ b/jam-ui/package-lock.json
@@ -1176,6 +1176,12 @@
"resolved": "https://registry.npmjs.org/@csstools/normalize.css/-/normalize.css-10.1.0.tgz",
"integrity": "sha512-ij4wRiunFfaJxjB0BdrYHIH8FxBJpOwNPhhAcunlmPdXudL1WQV1qoP9un6JsEBAgQH+7UXyyjh0g7jTxXK6tg=="
},
+ "@discoveryjs/json-ext": {
+ "version": "0.5.7",
+ "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz",
+ "integrity": "sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==",
+ "dev": true
+ },
"@emotion/cache": {
"version": "10.0.29",
"resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-10.0.29.tgz",
@@ -3097,6 +3103,27 @@
"@xtuc/long": "4.2.2"
}
},
+ "@webpack-cli/configtest": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/@webpack-cli/configtest/-/configtest-1.2.0.tgz",
+ "integrity": "sha512-4FB8Tj6xyVkyqjj1OaTqCjXYULB9FMkqQ8yGrZjRDrYh0nOE+7Lhs45WioWQQMV+ceFlE368Ukhe6xdvJM9Egg==",
+ "dev": true
+ },
+ "@webpack-cli/info": {
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/@webpack-cli/info/-/info-1.5.0.tgz",
+ "integrity": "sha512-e8tSXZpw2hPl2uMJY6fsMswaok5FdlGNRTktvFk2sD8RjH0hE2+XistawJx1vmKteh4NmGmNUrp+Tb2w+udPcQ==",
+ "dev": true,
+ "requires": {
+ "envinfo": "^7.7.3"
+ }
+ },
+ "@webpack-cli/serve": {
+ "version": "1.7.0",
+ "resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-1.7.0.tgz",
+ "integrity": "sha512-oxnCNGj88fL+xzV+dacXs44HcDwf1ovs3AuEzvP7mqXw7fQntqIhQ1BRmynh4qEKQSSSRSWVyXRjmTbZIX9V2Q==",
+ "dev": true
+ },
"@xtuc/ieee754": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz",
@@ -7185,6 +7212,12 @@
"resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz",
"integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A=="
},
+ "envinfo": {
+ "version": "7.8.1",
+ "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.8.1.tgz",
+ "integrity": "sha512-/o+BXHmB7ocbHEAs6F2EnG0ogybVVUdkRunTT2glZU9XAaGmhqskrvKwqXuDfNjEO0LZKWdejEEpnq8aM0tOaw==",
+ "dev": true
+ },
"errno": {
"version": "0.1.8",
"resolved": "https://registry.npmjs.org/errno/-/errno-0.1.8.tgz",
@@ -8209,6 +8242,12 @@
"resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
"integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc="
},
+ "fastest-levenshtein": {
+ "version": "1.0.16",
+ "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz",
+ "integrity": "sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==",
+ "dev": true
+ },
"faye-websocket": {
"version": "0.10.0",
"resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.10.0.tgz",
@@ -19706,6 +19745,164 @@
}
}
},
+ "webpack-cli": {
+ "version": "4.10.0",
+ "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-4.10.0.tgz",
+ "integrity": "sha512-NLhDfH/h4O6UOy+0LSso42xvYypClINuMNBVVzX4vX98TmTaTUxwRbXdhucbFMd2qLaCTcLq/PdYrvi8onw90w==",
+ "dev": true,
+ "requires": {
+ "@discoveryjs/json-ext": "^0.5.0",
+ "@webpack-cli/configtest": "^1.2.0",
+ "@webpack-cli/info": "^1.5.0",
+ "@webpack-cli/serve": "^1.7.0",
+ "colorette": "^2.0.14",
+ "commander": "^7.0.0",
+ "cross-spawn": "^7.0.3",
+ "fastest-levenshtein": "^1.0.12",
+ "import-local": "^3.0.2",
+ "interpret": "^2.2.0",
+ "rechoir": "^0.7.0",
+ "webpack-merge": "^5.7.3"
+ },
+ "dependencies": {
+ "colorette": {
+ "version": "2.0.19",
+ "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.19.tgz",
+ "integrity": "sha512-3tlv/dIP7FWvj3BsbHrGLJ6l/oKh1O3TcgBqMn+yyCagOxc23fyzDS6HypQbgxWbkpDnf52p1LuR4eWDQ/K9WQ==",
+ "dev": true
+ },
+ "commander": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz",
+ "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==",
+ "dev": true
+ },
+ "cross-spawn": {
+ "version": "7.0.3",
+ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
+ "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
+ "dev": true,
+ "requires": {
+ "path-key": "^3.1.0",
+ "shebang-command": "^2.0.0",
+ "which": "^2.0.1"
+ }
+ },
+ "find-up": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
+ "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
+ "dev": true,
+ "requires": {
+ "locate-path": "^5.0.0",
+ "path-exists": "^4.0.0"
+ }
+ },
+ "import-local": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz",
+ "integrity": "sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==",
+ "dev": true,
+ "requires": {
+ "pkg-dir": "^4.2.0",
+ "resolve-cwd": "^3.0.0"
+ }
+ },
+ "interpret": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/interpret/-/interpret-2.2.0.tgz",
+ "integrity": "sha512-Ju0Bz/cEia55xDwUWEa8+olFpCiQoypjnQySseKtmjNrnps3P+xfpUmGr90T7yjlVJmOtybRvPXhKMbHr+fWnw==",
+ "dev": true
+ },
+ "locate-path": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
+ "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
+ "dev": true,
+ "requires": {
+ "p-locate": "^4.1.0"
+ }
+ },
+ "p-locate": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz",
+ "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
+ "dev": true,
+ "requires": {
+ "p-limit": "^2.2.0"
+ }
+ },
+ "path-exists": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
+ "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
+ "dev": true
+ },
+ "path-key": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
+ "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
+ "dev": true
+ },
+ "pkg-dir": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz",
+ "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==",
+ "dev": true,
+ "requires": {
+ "find-up": "^4.0.0"
+ }
+ },
+ "rechoir": {
+ "version": "0.7.1",
+ "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.7.1.tgz",
+ "integrity": "sha512-/njmZ8s1wVeR6pjTZ+0nCnv8SpZNRMT2D1RLOJQESlYFDBvwpTA4KWJpZ+sBJ4+vhjILRcK7JIFdGCdxEAAitg==",
+ "dev": true,
+ "requires": {
+ "resolve": "^1.9.0"
+ }
+ },
+ "resolve-cwd": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz",
+ "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==",
+ "dev": true,
+ "requires": {
+ "resolve-from": "^5.0.0"
+ }
+ },
+ "resolve-from": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz",
+ "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==",
+ "dev": true
+ },
+ "shebang-command": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
+ "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
+ "dev": true,
+ "requires": {
+ "shebang-regex": "^3.0.0"
+ }
+ },
+ "shebang-regex": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
+ "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
+ "dev": true
+ },
+ "which": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
+ "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
+ "dev": true,
+ "requires": {
+ "isexe": "^2.0.0"
+ }
+ }
+ }
+ },
"webpack-dev-middleware": {
"version": "3.7.3",
"resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-3.7.3.tgz",
@@ -19939,6 +20136,44 @@
}
}
},
+ "webpack-merge": {
+ "version": "5.8.0",
+ "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-5.8.0.tgz",
+ "integrity": "sha512-/SaI7xY0831XwP6kzuwhKWVKDP9t1QY1h65lAFLbZqMPIuYcD9QAW4u9STIbU9kaJbPBB/geU/gLr1wDjOhQ+Q==",
+ "dev": true,
+ "requires": {
+ "clone-deep": "^4.0.1",
+ "wildcard": "^2.0.0"
+ },
+ "dependencies": {
+ "clone-deep": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz",
+ "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==",
+ "dev": true,
+ "requires": {
+ "is-plain-object": "^2.0.4",
+ "kind-of": "^6.0.2",
+ "shallow-clone": "^3.0.0"
+ }
+ },
+ "kind-of": {
+ "version": "6.0.3",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz",
+ "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==",
+ "dev": true
+ },
+ "shallow-clone": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz",
+ "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==",
+ "dev": true,
+ "requires": {
+ "kind-of": "^6.0.2"
+ }
+ }
+ }
+ },
"webpack-sources": {
"version": "1.4.3",
"resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.4.3.tgz",
@@ -20073,6 +20308,12 @@
}
}
},
+ "wildcard": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.0.tgz",
+ "integrity": "sha512-JcKqAHLPxcdb9KM49dufGXn2x3ssnfjbcaQdLlfZsL9rH9wgDQjUtDxbo8NE0F6SFvydeu1VhZe7hZuHsB2/pw==",
+ "dev": true
+ },
"word-wrap": {
"version": "1.2.3",
"resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz",
diff --git a/jam-ui/package.json b/jam-ui/package.json
index 8391b669b..2947d7bba 100644
--- a/jam-ui/package.json
+++ b/jam-ui/package.json
@@ -105,6 +105,7 @@
"gulp-sass": "^4.1.0",
"gulp-sourcemaps": "^2.6.5",
"prettier": "1.17.1",
- "swiper": "^6.8.2"
+ "swiper": "^6.8.2",
+ "webpack-cli": "^4.10.0"
}
}
diff --git a/jam-ui/src/components/page/JKPeopleFilter.js b/jam-ui/src/components/page/JKPeopleFilter.js
index f3eb9d085..3a42697ef 100644
--- a/jam-ui/src/components/page/JKPeopleFilter.js
+++ b/jam-ui/src/components/page/JKPeopleFilter.js
@@ -49,7 +49,7 @@ function JKPeopleFilter() {
instruments: [],
genres: [],
joined_within_days: '-1',
- active_within_days: '-1',
+ active_within_days: { value: '30', label: 'Within Last 30 Days' },
from_location: false,
}
});
diff --git a/ruby/lib/jam_ruby/models/base_search.rb b/ruby/lib/jam_ruby/models/base_search.rb
index 8e8ac9872..7ba937f47 100644
--- a/ruby/lib/jam_ruby/models/base_search.rb
+++ b/ruby/lib/jam_ruby/models/base_search.rb
@@ -200,10 +200,14 @@ module JamRuby
rel
end
+ def filter_includes(rel)
+ rel
+ end
+
def user_search_results(user_ids)
rel = do_filter(user_ids)
- rel = self.search_includes(rel)
- process_results_page(rel.all)
+ rel = self.filter_includes(rel)
+ process_results_page(rel.all, true) #skip_counters = true
end
def search_results_page(filter=nil, page=1, user_ids=nil)
diff --git a/ruby/lib/jam_ruby/models/musician_search.rb b/ruby/lib/jam_ruby/models/musician_search.rb
index b03562ca6..76da51354 100644
--- a/ruby/lib/jam_ruby/models/musician_search.rb
+++ b/ruby/lib/jam_ruby/models/musician_search.rb
@@ -176,9 +176,11 @@ module JamRuby
#NOTE: we can change to this once we upgrade postgresql
#rel = rel.where(id: user_ids).where('users.id <> ?', self.user.id).order("array_position(ARRAY[#{user_ids.map { |i| "'#{i}'" }.join(',')}], id::TEXT)")
- #rel = self._sort_by_ids_ordinality(rel, user_ids)
+ #rel = self._sort_by_ids_ordinality(rel, user_ids)
end
end
+
+ rel = rel.select("users.*, (SELECT count(friendships.id) > 0 AS is_friend FROM friendships WHERE friendships.user_id = users.id AND friendships.friend_id = '#{self.user.id}'), (SELECT count(follows.id) > 0 AS is_following FROM follows WHERE follows.user_id = users.id AND follows.followable_id = '#{self.user.id}' AND follows.followable_type = 'JamRuby::User'), (SELECT count(friend_requests.id) > 0 as pending_friend_request from friend_requests WHERE (friend_requests.user_id = '#{self.user.id}' AND friend_requests.friend_id = users.id) OR (friend_requests.user_id = users.id AND friend_requests.friend_id = '#{self.user.id}') )")
rel
end
@@ -203,35 +205,41 @@ module JamRuby
rel.includes([:instruments, :followings, :friends])
end
- def process_results_page(_results)
+ def filter_includes(rel)
+ rel.includes([:instruments, :genres])
+ end
+
+ def process_results_page(_results, skip_counters = false)
@results = _results
+
@user_counters = {} and return self unless user
- @user_counters = @results.inject({}) { |hh,val| hh[val.id] = []; hh }
- mids = "'#{@results.map(&:id).join("','")}'"
+ unless skip_counters
+ @user_counters = @results.inject({}) { |hh,val| hh[val.id] = []; hh }
+ mids = "'#{@results.map(&:id).join("','")}'"
- # this gets counts for each search result on friends/follows/records/sessions
- @results.each do |uu|
- counters = { }
- counters[COUNT_FRIEND] = Friendship.where(:user_id => uu.id).count
- counters[COUNT_FOLLOW] = Follow.where(:followable_id => uu.id).count
- counters[COUNT_RECORD] = ClaimedRecording.where(:user_id => uu.id).count
- counters[COUNT_SESSION] = MusicSession.where(:user_id => uu.id).count
- @user_counters[uu.id] << counters
+ # this gets counts for each search result on friends/follows/records/sessions
+ @results.each do |uu|
+ counters = { }
+ counters[COUNT_FRIEND] = Friendship.where(:user_id => uu.id).count
+ counters[COUNT_FOLLOW] = Follow.where(:followable_id => uu.id).count
+ counters[COUNT_RECORD] = ClaimedRecording.where(:user_id => uu.id).count
+ counters[COUNT_SESSION] = MusicSession.where(:user_id => uu.id).count
+ @user_counters[uu.id] << counters
+ end
+
+ # this section determines follow/like/friend status for each search result
+ # so that action links can be activated or not
+ rel = User.select("users.id AS uid")
+ rel = rel.joins("LEFT JOIN follows ON follows.user_id = '#{user.id}'")
+ rel = rel.where(["users.id IN (#{mids}) AND follows.followable_id = users.id"])
+ rel.all.each { |val| @user_counters[val.uid] << RESULT_FOLLOW }
+
+ rel = User.select("users.id AS uid")
+ rel = rel.joins("LEFT JOIN friendships AS friends ON friends.friend_id = '#{user.id}'")
+ rel = rel.where(["users.id IN (#{mids}) AND friends.user_id = users.id"])
+ rel.all.each { |val| @user_counters[val.uid] << RESULT_FRIEND }
end
-
- # this section determines follow/like/friend status for each search result
- # so that action links can be activated or not
- rel = User.select("users.id AS uid")
- rel = rel.joins("LEFT JOIN follows ON follows.user_id = '#{user.id}'")
- rel = rel.where(["users.id IN (#{mids}) AND follows.followable_id = users.id"])
- rel.all.each { |val| @user_counters[val.uid] << RESULT_FOLLOW }
-
- rel = User.select("users.id AS uid")
- rel = rel.joins("LEFT JOIN friendships AS friends ON friends.friend_id = '#{user.id}'")
- rel = rel.where(["users.id IN (#{mids}) AND friends.user_id = users.id"])
- rel.all.each { |val| @user_counters[val.uid] << RESULT_FRIEND }
-
self
end
diff --git a/web/app/controllers/api_search_controller.rb b/web/app/controllers/api_search_controller.rb
index bc67272be..f0e5a7b92 100644
--- a/web/app/controllers/api_search_controller.rb
+++ b/web/app/controllers/api_search_controller.rb
@@ -113,9 +113,9 @@ class ApiSearchController < ApiController
# filter_params.merge!(genres: genres)
# end
- beginner = ActiveRecord::Type::Boolean.new.type_cast_from_user(params[:proficiency_beginner])
- intermediate = ActiveRecord::Type::Boolean.new.type_cast_from_user(params[:proficiency_intermediate])
- expert = ActiveRecord::Type::Boolean.new.type_cast_from_user(params[:proficiency_expert])
+ beginner = ActiveRecord::Type::Boolean.new.type_cast_from_user(params[:proficiency_beginner])
+ intermediate = ActiveRecord::Type::Boolean.new.type_cast_from_user(params[:proficiency_intermediate])
+ expert = ActiveRecord::Type::Boolean.new.type_cast_from_user(params[:proficiency_expert])
proficiency_levels = []
proficiency_levels.push(1) if beginner
@@ -147,8 +147,7 @@ class ApiSearchController < ApiController
@latency_data = result[:data]
@offset = result[:offset]
- user_ids = @latency_data.map{ |l_data| l_data[:user_id] }
-
+ user_ids = @latency_data.map{ |l_data| l_data[:user_id] }
#end
# Bugsnag.notify("search_users_benchmark") do |report|
@@ -158,6 +157,7 @@ class ApiSearchController < ApiController
sobj = MusicianSearch.user_search_filter(current_user)
#@search = sobj.search_results_page(filter_params, page, user_ids)
+ #debugger
@search = sobj.user_search_results(user_ids)
respond_with @search, responder: ApiResponder, status: 201, template: 'api_search/filter'
diff --git a/web/app/views/api_search/filter.rabl b/web/app/views/api_search/filter.rabl
index 4fc5a360e..8ba80bccd 100644
--- a/web/app/views/api_search/filter.rabl
+++ b/web/app/views/api_search/filter.rabl
@@ -25,19 +25,19 @@ node :is_blank_filter do |foo|
end
child(:results => :musicians) {
- attributes :id, :first_name, :last_name, :name, :city, :state, :country, :online, :musician, :photo_url, :biography, :regionname, :score, :full_score
+ attributes :id, :first_name, :last_name, :name, :city, :state, :country, :online, :musician, :photo_url, :biography, :regionname, :score, :full_score, :is_friend, :is_following, :pending_friend_request
- node :is_friend do |musician|
- @search.is_friend?(musician)
- end
+ # node :is_friend do |musician|
+ # @search.is_friend?(musician)
+ # end
- node :is_following do |musician|
- @search.is_follower?(musician)
- end
+ # node :is_following do |musician|
+ # @search.is_follower?(musician)
+ # end
- node :pending_friend_request do |musician|
- musician.pending_friend_request?(current_user)
- end
+ # node :pending_friend_request do |musician|
+ # musician.pending_friend_request?(current_user)
+ # end
node :biography do |musician|
musician.biography.nil? ? "" : musician.biography
@@ -47,16 +47,16 @@ child(:results => :musicians) {
attributes :instrument_id, :description, :proficiency_level, :priority
end
- child :top_followings => :followings do |uf|
- node :user_id do |uu| uu.id end
- node :photo_url do |uu| uu.photo_url end
- node :name do |uu| uu.name end
- end
+ # child :top_followings => :followings do |uf|
+ # node :user_id do |uu| uu.id end
+ # node :photo_url do |uu| uu.photo_url end
+ # node :name do |uu| uu.name end
+ # end
- node :friend_count do |musician| @search.friend_count(musician) end
- node :follow_count do |musician| @search.follow_count(musician) end
- node :recording_count do |musician| @search.record_count(musician) end
- node :session_count do |musician| @search.session_count(musician) end
+ # node :friend_count do |musician| @search.friend_count(musician) end
+ # node :follow_count do |musician| @search.follow_count(musician) end
+ # node :recording_count do |musician| @search.record_count(musician) end
+ # node :session_count do |musician| @search.session_count(musician) end
node :audio_latency do |musician|
last_jam_audio_latency(musician)
@@ -65,10 +65,19 @@ child(:results => :musicians) {
node :latency_data do |musician|
if latency = @latency_data.detect{|l_data| l_data[:user_id] == musician.id }
+ audio_latency = latency[:audio_latency].to_i
+ internet_latency = latency[:ars_internet_latency].to_i
+ total_letency = latency[:ars_total_latency]
+ #sometimes neo4j returns 0 for audio latency. this is not correct.
+ #when this happens as a temporary hack we default audio latency to 5.
+ if audio_latency <= 0
+ audio_latency = 5
+ total_letency = audio_latency + internet_latency
+ end
{
- audio_latency: latency[:audio_latency],
- ars_internet_latency: latency[:ars_internet_latency],
- ars_total_latency: latency[:ars_total_latency]
+ audio_latency: audio_latency,
+ ars_internet_latency: internet_latency,
+ ars_total_latency: total_letency
}
end if @latency_data
end
diff --git a/web/spec/requests/musician_filter_api_spec.rb b/web/spec/requests/musician_filter_api_spec.rb
index 677b79872..702ac5f0c 100644
--- a/web/spec/requests/musician_filter_api_spec.rb
+++ b/web/spec/requests/musician_filter_api_spec.rb
@@ -13,7 +13,8 @@ describe "Musician Filter API", type: :request do
let(:user5) { FactoryGirl.create(:user) }
let(:user6) { FactoryGirl.create(:user) }
let(:user7) { FactoryGirl.create(:user) }
-
+ let(:user8) { FactoryGirl.create(:user) }
+
let(:latency_data_uri) { /\S+\/search_users/ }
let(:response_body) { mock_latency_response([
@@ -23,7 +24,8 @@ describe "Musician Filter API", type: :request do
{ user: user4, ars_total_latency: 60.0, ars_internet_latency: 30, audio_latency: 30.0 }, #FAIR
{ user: user5, ars_total_latency: 60.1, ars_internet_latency: 30.1, audio_latency: 30 }, #HIGH
{ user: user6, ars_total_latency: 100.0, ars_internet_latency: 50.0, audio_latency: 50.0 }, #HIGH
- { user: user7, ars_total_latency: -2, ars_internet_latency: -1, audio_latency: -1 } #UNKNOWN
+ { user: user7, ars_total_latency: -2, ars_internet_latency: -1, audio_latency: -1 }, #UNKNOWN
+ { user: user8, ars_total_latency: 10, ars_internet_latency: 5, audio_latency: 0 } #GOOD (NOTE: audio_latency from neo4j is 0 here)
])
}
@@ -128,22 +130,28 @@ describe "Musician Filter API", type: :request do
it "get all musicians" do
get '/api/search/musicians.json?results=true'
- expect(JSON.parse(response.body)["musicians"].size).to eq(7)
+ expect(JSON.parse(response.body)["musicians"].size).to eq(8)
end
it "filter musicians when no latency option is selected" do
post '/api/filter.json', { latency_good: false, latency_fair: false, latency_high: false }
- expect(JSON.parse(response.body)["musicians"].size).to eq(7)
+ expect(JSON.parse(response.body)["musicians"].size).to eq(8)
expect(JSON.parse(response.body)["musicians"][0]["latency_data"]).not_to eq(nil)
expect(JSON.parse(response.body)["musicians"][0]["latency_data"]["audio_latency"]).not_to eq(nil)
expect(JSON.parse(response.body)["musicians"][0]["latency_data"]["ars_internet_latency"]).not_to eq(nil)
expect(JSON.parse(response.body)["musicians"][0]["latency_data"]["ars_total_latency"]).not_to eq(nil)
+ expect(JSON.parse(response.body)["musicians"][0]["latency_data"]["audio_latency"]).to eq(5)
+ end
+
+ it "set audio latency to 5ms when the returned value is 0" do
+ post '/api/filter.json', { latency_good: false, latency_fair: false, latency_high: false }
+ expect(JSON.parse(response.body)["musicians"][7]["latency_data"]["audio_latency"]).to eq(5)
end
it "filter musicians for all latency options" do
post '/api/filter.json', { latency_good: true, latency_fair: true, latency_high: true }
- expect(JSON.parse(response.body)["musicians"].size).to eq(6)
+ expect(JSON.parse(response.body)["musicians"].size).to eq(7)
expect(JSON.parse(response.body)["musicians"][0]["latency_data"]).not_to eq(nil)
expect(JSON.parse(response.body)["musicians"][0]["latency_data"]["audio_latency"]).not_to eq(nil)
expect(JSON.parse(response.body)["musicians"][0]["latency_data"]["ars_internet_latency"]).not_to eq(nil)
@@ -156,6 +164,7 @@ describe "Musician Filter API", type: :request do
expect(JSON.parse(response.body)["musicians"][3]["id"]).to eq(user4.id)
expect(JSON.parse(response.body)["musicians"][4]["id"]).to eq(user5.id)
expect(JSON.parse(response.body)["musicians"][5]["id"]).to eq(user6.id)
+ expect(JSON.parse(response.body)["musicians"][6]["id"]).to eq(user8.id)
end
it "filter GOOD latency users" do
@@ -163,7 +172,7 @@ describe "Musician Filter API", type: :request do
expect(response.content_type).to eq("application/json")
expect(response).to render_template(:filter)
expect(response).to have_http_status(:created)
- expect(JSON.parse(response.body)["musicians"].size).to eq(2)
+ expect(JSON.parse(response.body)["musicians"].size).to eq(3)
#test latency data
expect(JSON.parse(response.body)["musicians"][0]["latency_data"]).not_to eq(nil)
@@ -184,17 +193,17 @@ describe "Musician Filter API", type: :request do
it "filter GOOD and FAIR latency musicians" do
post '/api/filter.json', { latency_good: true, latency_fair: true, latency_high: false }
- expect(JSON.parse(response.body)["musicians"].size).to eq(4)
+ expect(JSON.parse(response.body)["musicians"].size).to eq(5)
end
it "filter GOOD and HIGH latency musicians" do
post '/api/filter.json', { latency_good: true, latency_fair: false, latency_high: true }
- expect(JSON.parse(response.body)["musicians"].size).to eq(4)
+ expect(JSON.parse(response.body)["musicians"].size).to eq(5)
end
it "filter GOOD, FAIR and HIGH latency musicians" do
post '/api/filter.json', { latency_good: true, latency_fair: true, latency_high: true }
- expect(JSON.parse(response.body)["musicians"].size).to eq(6)
+ expect(JSON.parse(response.body)["musicians"].size).to eq(7)
end
it "filter musicians by genres" do