Commit 2eab725

mo <mo.khan@gmail.com>
2019-06-15 19:16:19
support not op on all operators
1 parent 0664989
Changed files (2)
app
models
spec
models
app/models/scim/visitor.rb
@@ -50,45 +50,87 @@ module Scim
     end
 
     def visit_not_equals(node)
-      @clazz.where.not(attr_for(node) => node.value)
+      if node.not?
+        @clazz.where(attr_for(node) => node.value)
+      else
+        @clazz.where.not(attr_for(node) => node.value)
+      end
     end
 
     def visit_contains(node)
-      @clazz.where(
-        "#{attr_for(node)} LIKE ?", "%#{escape_sql_wildcards(node.value)}%"
-      )
+      if node.not?
+        @clazz.where.not(
+          "#{attr_for(node)} LIKE ?", "%#{escape_sql_wildcards(node.value)}%"
+        )
+      else
+        @clazz.where(
+          "#{attr_for(node)} LIKE ?", "%#{escape_sql_wildcards(node.value)}%"
+        )
+      end
     end
 
     def visit_starts_with(node)
-      @clazz.where(
-        "#{attr_for(node)} LIKE ?", "#{escape_sql_wildcards(node.value)}%"
-      )
+      if node.not?
+        @clazz.where.not(
+          "#{attr_for(node)} LIKE ?", "#{escape_sql_wildcards(node.value)}%"
+        )
+      else
+        @clazz.where(
+          "#{attr_for(node)} LIKE ?", "#{escape_sql_wildcards(node.value)}%"
+        )
+      end
     end
 
     def visit_ends_with(node)
-      @clazz.where(
-        "#{attr_for(node)} LIKE ?", "%#{escape_sql_wildcards(node.value)}"
-      )
+      if node.not?
+        @clazz.where.not(
+          "#{attr_for(node)} LIKE ?", "%#{escape_sql_wildcards(node.value)}"
+        )
+      else
+        @clazz.where(
+          "#{attr_for(node)} LIKE ?", "%#{escape_sql_wildcards(node.value)}"
+        )
+      end
     end
 
     def visit_greater_than(node)
-      @clazz.where("#{attr_for(node)} > ?", cast_value_from(node))
+      if node.not?
+        @clazz.where.not("#{attr_for(node)} > ?", cast_value_from(node))
+      else
+        @clazz.where("#{attr_for(node)} > ?", cast_value_from(node))
+      end
     end
 
     def visit_greater_than_equals(node)
-      @clazz.where("#{attr_for(node)} >= ?", cast_value_from(node))
+      if node.not?
+        @clazz.where.not("#{attr_for(node)} >= ?", cast_value_from(node))
+      else
+        @clazz.where("#{attr_for(node)} >= ?", cast_value_from(node))
+      end
     end
 
     def visit_less_than(node)
-      @clazz.where("#{attr_for(node)} < ?", cast_value_from(node))
+      if node.not?
+        @clazz.where.not("#{attr_for(node)} < ?", cast_value_from(node))
+      else
+        @clazz.where("#{attr_for(node)} < ?", cast_value_from(node))
+      end
     end
 
     def visit_less_than_equals(node)
-      @clazz.where("#{attr_for(node)} <= ?", cast_value_from(node))
+      if node.not?
+        @clazz.where.not("#{attr_for(node)} <= ?", cast_value_from(node))
+      else
+        @clazz.where("#{attr_for(node)} <= ?", cast_value_from(node))
+      end
     end
 
     def visit_presence(node)
-      @clazz.where.not(attr_for(node) => nil)
+      if node.not?
+        @clazz.where(attr_for(node) => nil)
+      else
+        @clazz.where.not(attr_for(node) => nil)
+      end
     end
 
     def visit_unknown(_node)
spec/models/scim/search_spec.rb
@@ -20,6 +20,55 @@ RSpec.describe ::Scim::Search do
       expect(results).to match_array(users - [random_user])
     end
 
+    specify do
+      results = subject.for("userName pr and not (userName co \"#{random_user.email}\")")
+      expect(results).to match_array(users - [random_user])
+    end
+
+    specify do
+      results = subject.for("userName pr and not (userName ew \"#{random_user.email}\")")
+      expect(results).to match_array(users - [random_user])
+    end
+
+    specify do
+      random_user.update(updated_at: 10.minutes.from_now)
+      results = subject.for("userName pr and not (meta.lastModified ge \"#{5.minutes.from_now.iso8601}\")")
+      expect(results).to match_array(users - [random_user])
+    end
+
+    specify do
+      random_user.update(updated_at: 10.minutes.from_now)
+      results = subject.for("userName pr and not (meta.lastModified gt \"#{5.minutes.from_now.iso8601}\")")
+      expect(results).to match_array(users - [random_user])
+    end
+
+    specify do
+      random_user.update(updated_at: 10.minutes.from_now)
+      results = subject.for("userName pr and not (meta.lastModified le \"#{5.minutes.from_now.iso8601}\")")
+      expect(results).to match_array([random_user])
+    end
+
+    specify do
+      random_user.update(updated_at: 10.minutes.from_now)
+      results = subject.for("userName pr and not (meta.lastModified lt \"#{5.minutes.from_now.iso8601}\")")
+      expect(results).to match_array([random_user])
+    end
+
+    specify do
+      results = subject.for("userName pr and not (userName ne \"#{random_user.email}\")")
+      expect(results).to match_array([random_user])
+    end
+
+    specify do
+      results = subject.for("not (userName pr)")
+      expect(results).to match_array([])
+    end
+
+    specify do
+      results = subject.for("userName pr and not (userName sw \"#{random_user.email}\")")
+      expect(results).to match_array(users - [random_user])
+    end
+
     specify do
       results = subject.for("userName eq \"#{random_user.email}\"")
       expect(results).to match_array([random_user])