wcc-contentful 1.1.0 → 1.1.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f99e076627c9facfff117f6d9df87dcf593d8a07bb6d3351b159172207aff81a
4
- data.tar.gz: 463c6b34cbf4a5718736e04365a9705795fd1f3435167cc1028d5c217596fb34
3
+ metadata.gz: 964aa9bb9b781c8ca90803f8117130daf1aac1ea88324ab64237b0e2a6a6c328
4
+ data.tar.gz: 834dd56d5e39fdad058efa794f1e5022b92d9122463c827d91d85ffcd9dbe291
5
5
  SHA512:
6
- metadata.gz: 4be52c0f698f59b61f91d547ae7a2588b07bc9d184cd09a78730f7a09b290d005770b4f1ab3306d7e9cbc9ca0e5a20c7dc3c63fa39417a7c3219bf4c28ecd8a8
7
- data.tar.gz: a1e93027a2a81655f9dbe82ee54c4f77061ef757c2dee9e3fe12369ce9f8d698fd01a7ab9a2510244273f567dbbdb05084eeb3b333abcafce9ccb05c6e62c4bc
6
+ metadata.gz: ff532ebd5b3750554a63786877d846c724e5edb28796f964977b7bc03064eada4ea3c608d0b0809a4306306c5bb75dfedc0ed5fa670ef7fb2b224b39ebcaafcc
7
+ data.tar.gz: '0886f5a8caad820a963af4d37a07fb319ae5cfc8735f400f41eb22131df9f90477b966d91f3e2f26e40bffc1579bcbc9bba2dd351cb677a28df90dea87368eef'
@@ -13,18 +13,17 @@ module WCC::Contentful
13
13
  client = WCC::Contentful::SimpleClient::Management.new(
14
14
  args
15
15
  )
16
- enable_webhook(client, args.slice(:app_url, :webhook_username, :webhook_password))
16
+ enable_webhook(client, args.slice(:receive_url, :webhook_username, :webhook_password))
17
17
  end
18
18
 
19
- def enable_webhook(client, app_url:, webhook_username: nil, webhook_password: nil)
20
- expected_url = URI.join(app_url, 'webhook/receive').to_s
21
- webhook = client.webhook_definitions.items.find { |w| w['url'] == expected_url }
19
+ def enable_webhook(client, receive_url:, webhook_username: nil, webhook_password: nil)
20
+ webhook = client.webhook_definitions.items.find { |w| w['url'] == receive_url }
22
21
  logger.debug "existing webhook: #{webhook.inspect}" if webhook
23
22
  return if webhook
24
23
 
25
24
  body = {
26
25
  'name' => 'WCC::Contentful webhook',
27
- 'url' => expected_url,
26
+ 'url' => receive_url,
28
27
  'topics' => [
29
28
  '*.publish',
30
29
  '*.unpublish'
@@ -50,13 +49,14 @@ module WCC::Contentful
50
49
 
51
50
  {
52
51
  management_token: config.management_token,
53
- app_url: config.app_url,
54
52
  space: config.space,
55
53
  environment: config.environment,
56
54
  default_locale: config.default_locale,
57
55
  connection: config.connection,
58
56
  webhook_username: config.webhook_username,
59
- webhook_password: config.webhook_password
57
+ webhook_password: config.webhook_password,
58
+
59
+ receive_url: URI.join(config.app_url, 'webhook/receive').to_s
60
60
  }
61
61
  end
62
62
 
@@ -105,6 +105,11 @@ module WCC::Contentful::Store
105
105
 
106
106
  def apply_operator(operator, field, expected, context = nil)
107
107
  op = operator == :eq ? nil : operator
108
+ if expected.is_a?(Array)
109
+ expected = expected.join(',')
110
+ op = :in if op.nil?
111
+ end
112
+
108
113
  param = parameter(field, operator: op, context: context, locale: true)
109
114
 
110
115
  self.class.new(
@@ -38,7 +38,13 @@ module WCC::Contentful::Store
38
38
  end
39
39
  end
40
40
 
41
+ SUPPORTED_OPS = %i[eq ne in nin].freeze
42
+
41
43
  def execute(query)
44
+ (query.conditions.map(&:op) - SUPPORTED_OPS).each do |op|
45
+ raise ArgumentError, "Operator :#{op} not supported"
46
+ end
47
+
42
48
  relation = mutex.with_read_lock { @hash.values }
43
49
 
44
50
  # relation is an enumerable that we apply conditions to in the form of
@@ -56,21 +62,49 @@ module WCC::Contentful::Store
56
62
  # For each condition, we apply a new Enumerable#select with a block that
57
63
  # enforces the condition.
58
64
  query.conditions.reduce(relation) do |memo, condition|
59
- memo.select do |entry|
60
- # Our naiive implementation only supports equality operator
61
- raise ArgumentError, "Operator #{condition.op} not supported" unless condition.op == :eq
65
+ __send__("apply_#{condition.op}", memo, condition)
66
+ end
67
+ end
62
68
 
63
- # The condition's path tells us where to find the value in the JSON object
64
- val = entry.dig(*condition.path)
69
+ private
65
70
 
66
- # For arrays, equality is defined as does the array include the expected value.
67
- # See https://www.contentful.com/developers/docs/references/content-delivery-api/#/reference/search-parameters/array-equality-inequality
68
- if val.is_a? Array
69
- val.include?(condition.expected)
70
- else
71
- val == condition.expected
72
- end
73
- end
71
+ def apply_eq(memo, condition)
72
+ memo.select { |entry| eq?(entry, condition) }
73
+ end
74
+
75
+ def apply_ne(memo, condition)
76
+ memo.reject { |entry| eq?(entry, condition) }
77
+ end
78
+
79
+ def eq?(entry, condition)
80
+ # The condition's path tells us where to find the value in the JSON object
81
+ val = entry.dig(*condition.path)
82
+
83
+ # For arrays, equality is defined as does the array include the expected value.
84
+ # See https://www.contentful.com/developers/docs/references/content-delivery-api/#/reference/search-parameters/array-equality-inequality
85
+ if val.is_a? Array
86
+ val.include?(condition.expected)
87
+ else
88
+ val == condition.expected
89
+ end
90
+ end
91
+
92
+ def apply_in(memo, condition)
93
+ memo.select { |entry| in?(entry, condition) }
94
+ end
95
+
96
+ def apply_nin(memo, condition)
97
+ memo.reject { |entry| in?(entry, condition) }
98
+ end
99
+
100
+ def in?(entry, condition)
101
+ val = entry.dig(*condition.path)
102
+
103
+ if val.is_a? Array
104
+ # TODO: detect if in ruby 3.1 and use val.intersect?(condition.expected)
105
+ val.any? { |item| condition.expected.include?(item) }
106
+ else
107
+ condition.expected.include?(val)
74
108
  end
75
109
  end
76
110
  end
@@ -34,6 +34,17 @@ module WCC::Contentful::Store
34
34
  @extra = extra
35
35
  end
36
36
 
37
+ FALSE_VALUES = [
38
+ false, 0,
39
+ '0', :"0",
40
+ 'f', :f,
41
+ 'F', :F,
42
+ 'false', :false, # rubocop:disable Lint/BooleanSymbol
43
+ 'FALSE', :FALSE,
44
+ 'off', :off,
45
+ 'OFF', :OFF
46
+ ].to_set.freeze
47
+
37
48
  # Returns a new chained Query that has a new condition. The new condition
38
49
  # represents the WHERE comparison being applied here. The underlying store
39
50
  # implementation translates this condition statement into an appropriate
@@ -50,7 +61,16 @@ module WCC::Contentful::Store
50
61
  # @expected The expected value to compare the field's value against.
51
62
  # @context A context object optionally containing `context[:locale]`
52
63
  def apply_operator(operator, field, expected, context = nil)
64
+ operator ||= expected.is_a?(Array) ? :in : :eq
53
65
  raise ArgumentError, "Operator #{operator} not supported" unless respond_to?(operator)
66
+ raise ArgumentError, 'value cannot be nil (try using exists: false)' if expected.nil?
67
+
68
+ case operator
69
+ when :in, :nin, :all
70
+ expected = Array(expected)
71
+ when :exists
72
+ expected = !FALSE_VALUES.include?(expected)
73
+ end
54
74
 
55
75
  field = field.to_s if field.is_a? Symbol
56
76
  path = field.is_a?(Array) ? field : field.split('.')
@@ -151,7 +171,7 @@ module WCC::Contentful::Store
151
171
  elsif op?(k)
152
172
  { path: path, op: k.to_sym, expected: v }
153
173
  else
154
- { path: path + [k], op: :eq, expected: v }
174
+ { path: path + [k], op: nil, expected: v }
155
175
  end
156
176
  end
157
177
  end
@@ -528,68 +528,6 @@ RSpec.shared_examples 'basic store' do
528
528
  expect(found.dig('sys', 'id')).to eq('idTwo')
529
529
  expect(found.dig('fields', 'system', 'en-US')).to eq('Two')
530
530
  end
531
-
532
- [
533
- [Integer, proc { rand(-4_611_686_018_427_387_903..4_611_686_018_427_387_903) }],
534
- [Float, proc { rand }]
535
- ].each do |(type, generator)|
536
- context "by #{type} equality" do
537
- it 'can apply filter object' do
538
- data =
539
- 1.upto(10).map do |i|
540
- {
541
- 'sys' => { 'id' => "k#{i}", 'contentType' => { 'sys' => { 'id' => 'test1' } } },
542
- 'fields' => { type.to_s => { 'en-US' => generator.call } }
543
- }
544
- end
545
-
546
- desired_value = generator.call
547
- desired = {
548
- 'sys' => { 'id' => "k#{rand}", 'contentType' => { 'sys' => { 'id' => 'test1' } } },
549
- 'fields' => { type.to_s => { 'en-US' => desired_value } }
550
- }
551
-
552
- data << desired
553
- data.shuffle.each { |d| subject.set(d.dig('sys', 'id'), d) }
554
-
555
- # act
556
- found = subject.find_by(content_type: 'test1', filter: { type.to_s => desired_value })
557
-
558
- # assert
559
- expect(found).to_not be_nil
560
- expect(found).to eq(desired)
561
- end
562
-
563
- it 'filter object can find value in array' do
564
- data =
565
- 1.upto(10).map do |i|
566
- {
567
- 'sys' => {
568
- 'id' => "k#{i}",
569
- 'contentType' => { 'sys' => { 'id' => 'test1' } }
570
- },
571
- 'fields' => { 'name' => { 'en-US' => [generator.call, generator.call] } }
572
- }
573
- end
574
-
575
- desired_value = generator.call
576
- desired = {
577
- 'sys' => { 'id' => "k#{rand}", 'contentType' => { 'sys' => { 'id' => 'test1' } } },
578
- 'fields' => { type.to_s => { 'en-US' => [generator.call, desired_value].shuffle } }
579
- }
580
-
581
- data << desired
582
- data.shuffle.each { |d| subject.set(d.dig('sys', 'id'), d) }
583
-
584
- # act
585
- found = subject.find_by(content_type: 'test1', filter: { type.to_s => { eq: desired_value } })
586
-
587
- # assert
588
- expect(found).to_not be_nil
589
- expect(found).to eq(desired)
590
- end
591
- end
592
- end
593
531
  end
594
532
 
595
533
  describe '#find_all' do
@@ -634,29 +572,6 @@ RSpec.shared_examples 'basic store' do
634
572
  %w[k1 k5 k9]
635
573
  )
636
574
  end
637
-
638
- it 'filter query eq can find value in array' do
639
- content_types = %w[test1 test2 test3 test4]
640
- data =
641
- 1.upto(10).map do |i|
642
- {
643
- 'sys' => {
644
- 'id' => "k#{i}",
645
- 'contentType' => { 'sys' => { 'id' => content_types[i % content_types.length] } }
646
- },
647
- 'fields' => { 'name' => { 'en-US' => ["test#{i}", "test_2_#{i}"] } }
648
- }
649
- end
650
- data.each { |d| subject.set(d.dig('sys', 'id'), d) }
651
-
652
- # act
653
- found = subject.find_all(content_type: 'test2')
654
- .apply('name' => { eq: 'test_2_5' })
655
-
656
- # assert
657
- expect(found.count).to eq(1)
658
- expect(found.first.dig('sys', 'id')).to eq('k5')
659
- end
660
575
  end
661
576
 
662
577
  def make_link_to(id, link_type = 'Entry')
@@ -0,0 +1,92 @@
1
+ # frozen_string_literal: true
2
+
3
+ RSpec.shared_examples 'supports :eq operator' do
4
+ [
5
+ [String, proc { "test#{rand(1..10_000)}" }],
6
+ [Integer, proc { rand(-4_611_686_018_427_387_903..4_611_686_018_427_387_903) }],
7
+ [Float, proc { rand }]
8
+ ].each do |(type, generator)|
9
+ context "with #{type} value" do
10
+ let(:desired_value) {
11
+ generator.call
12
+ }
13
+
14
+ let(:data) {
15
+ 1.upto(3).map do |i|
16
+ {
17
+ 'sys' => { 'id' => "k#{i}", 'contentType' => { 'sys' => { 'id' => 'test1' } } },
18
+ 'fields' => { type.to_s => { 'en-US' => generator.call } }
19
+ }
20
+ end
21
+ }
22
+
23
+ let(:desired) {
24
+ {
25
+ 'sys' => { 'id' => "k#{rand}", 'contentType' => { 'sys' => { 'id' => 'test1' } } },
26
+ 'fields' => { type.to_s => { 'en-US' => desired_value } }
27
+ }
28
+ }
29
+
30
+ it 'find_by can apply filter object' do
31
+ [*data, desired].shuffle.each { |d| subject.set(d.dig('sys', 'id'), d) }
32
+
33
+ # act
34
+ found = subject.find_by(content_type: 'test1', filter: { type.to_s => desired_value })
35
+
36
+ # assert
37
+ expect(found).to_not be_nil
38
+ expect(found).to eq(desired)
39
+ end
40
+
41
+ it 'find_by can find value in array' do
42
+ data =
43
+ 1.upto(3).map do |i|
44
+ {
45
+ 'sys' => {
46
+ 'id' => "k#{i}",
47
+ 'contentType' => { 'sys' => { 'id' => 'test1' } }
48
+ },
49
+ 'fields' => { 'name' => { 'en-US' => [generator.call, generator.call] } }
50
+ }
51
+ end
52
+
53
+ desired_value = generator.call
54
+ desired = {
55
+ 'sys' => { 'id' => "k#{rand}", 'contentType' => { 'sys' => { 'id' => 'test1' } } },
56
+ 'fields' => { type.to_s => { 'en-US' => [generator.call, desired_value].shuffle } }
57
+ }
58
+
59
+ data << desired
60
+ data.shuffle.each { |d| subject.set(d.dig('sys', 'id'), d) }
61
+
62
+ # act
63
+ found = subject.find_by(content_type: 'test1', filter: { type.to_s => { eq: desired_value } })
64
+
65
+ # assert
66
+ expect(found).to_not be_nil
67
+ expect(found).to eq(desired)
68
+ end
69
+
70
+ it 'find_all can apply operator' do
71
+ desired =
72
+ 4.upto(5).map do |i|
73
+ {
74
+ 'sys' => { 'id' => "k#{i}", 'contentType' => { 'sys' => { 'id' => 'test1' } } },
75
+ 'fields' => { type.to_s => { 'en-US' => desired_value } }
76
+ }
77
+ end
78
+
79
+ [*data, *desired].shuffle.each { |d| subject.set(d.dig('sys', 'id'), d) }
80
+
81
+ # act
82
+ found = subject.find_all(content_type: 'test1')
83
+ .eq(type.to_s, desired_value)
84
+
85
+ # assert
86
+ expect(found.count).to eq(2)
87
+ sorted = found.to_a.sort_by { |item| item.dig('sys', 'id') }
88
+ expect(sorted).to eq(desired)
89
+ end
90
+ end
91
+ end
92
+ end
@@ -0,0 +1,131 @@
1
+ # frozen_string_literal: true
2
+
3
+ RSpec.shared_examples 'supports :in operator' do
4
+ it 'find_all with array on string field' do
5
+ ids = 1.upto(10).to_a
6
+ data =
7
+ ids.map do |i|
8
+ {
9
+ 'sys' => {
10
+ 'id' => "k#{i}",
11
+ 'contentType' => { 'sys' => { 'id' => 'test' } }
12
+ },
13
+ 'fields' => { 'name' => { 'en-US' => "test#{i}" } }
14
+ }
15
+ end
16
+ data.each { |d| subject.set(d.dig('sys', 'id'), d) }
17
+
18
+ to_find = ids.shuffle.take(2)
19
+
20
+ # act
21
+ found = subject.find_all(content_type: 'test')
22
+ .in('name', to_find.map { |i| "test#{i}" })
23
+
24
+ expect(found.count).to eq(2)
25
+ expect(found.map { |item| item.dig('sys', 'id') }.sort).to eq(
26
+ to_find.map { |i| "k#{i}" }.sort
27
+ )
28
+ end
29
+
30
+ it 'find_all with array on array field' do
31
+ ids = 1.upto(10).to_a
32
+ data =
33
+ ids.map do |i|
34
+ {
35
+ 'sys' => {
36
+ 'id' => "k#{i}",
37
+ 'contentType' => { 'sys' => { 'id' => 'test' } }
38
+ },
39
+ 'fields' => { 'name' => { 'en-US' => ["test#{i}", "test_2_#{i}"] } }
40
+ }
41
+ end
42
+ data.each { |d| subject.set(d.dig('sys', 'id'), d) }
43
+
44
+ to_find1, to_find2 = ids.shuffle
45
+
46
+ # act
47
+ found = subject.find_all(content_type: 'test')
48
+ .in('name', ["test#{to_find1}", "test_2_#{to_find2}"])
49
+
50
+ expect(found.count).to eq(2)
51
+ expect(found.map { |item| item.dig('sys', 'id') }.sort).to eq(
52
+ ["k#{to_find1}", "k#{to_find2}"].sort
53
+ )
54
+ end
55
+
56
+ it 'find_all defaults to :in when given an array' do
57
+ ids = 1.upto(10).to_a
58
+ data =
59
+ ids.map do |i|
60
+ {
61
+ 'sys' => {
62
+ 'id' => "k#{i}",
63
+ 'contentType' => { 'sys' => { 'id' => 'test' } }
64
+ },
65
+ 'fields' => { 'name' => { 'en-US' => "test#{i}" } }
66
+ }
67
+ end
68
+ data.each { |d| subject.set(d.dig('sys', 'id'), d) }
69
+
70
+ to_find = ids.shuffle.take(3)
71
+
72
+ # act
73
+ found = subject.find_all(content_type: 'test')
74
+ .apply('name' => to_find.map { |i| "test#{i}" })
75
+
76
+ expect(found.count).to eq(3)
77
+ expect(found.map { |item| item.dig('sys', 'id') }.sort).to eq(
78
+ to_find.map { |i| "k#{i}" }.sort
79
+ )
80
+ end
81
+
82
+ it 'find_by with array on string field' do
83
+ ids = 1.upto(10).to_a
84
+ data =
85
+ ids.map do |i|
86
+ {
87
+ 'sys' => {
88
+ 'id' => "k#{i}",
89
+ 'contentType' => { 'sys' => { 'id' => 'test' } }
90
+ },
91
+ 'fields' => { 'name' => { 'en-US' => "test#{i}" } }
92
+ }
93
+ end
94
+ data.each { |d| subject.set(d.dig('sys', 'id'), d) }
95
+
96
+ to_find = ids.sample
97
+
98
+ # act
99
+ found = subject.find_by(
100
+ content_type: 'test',
101
+ filter: { name: { in: ['asdf', "test#{to_find}"] } }
102
+ )
103
+
104
+ expect(found.dig('sys', 'id')).to eq("k#{to_find}")
105
+ end
106
+
107
+ it 'find_by defaults to :in when given an array' do
108
+ ids = 1.upto(10).to_a
109
+ data =
110
+ ids.map do |i|
111
+ {
112
+ 'sys' => {
113
+ 'id' => "k#{i}",
114
+ 'contentType' => { 'sys' => { 'id' => 'test' } }
115
+ },
116
+ 'fields' => { 'name' => { 'en-US' => "test#{i}" } }
117
+ }
118
+ end
119
+ data.each { |d| subject.set(d.dig('sys', 'id'), d) }
120
+
121
+ to_find = ids.sample
122
+
123
+ # act
124
+ found = subject.find_by(
125
+ content_type: 'test',
126
+ filter: { name: ['asdf', "test#{to_find}"] }
127
+ )
128
+
129
+ expect(found.dig('sys', 'id')).to eq("k#{to_find}")
130
+ end
131
+ end
@@ -0,0 +1,77 @@
1
+ # frozen_string_literal: true
2
+
3
+ RSpec.shared_examples 'supports :ne operator' do
4
+ [
5
+ [String, proc { "test#{rand(1..100_000)}" }],
6
+ [Integer, proc { rand(-4_611_686_018_427_387_903..4_611_686_018_427_387_903) }],
7
+ [Float, proc { rand }]
8
+ ].each do |(type, generator)|
9
+ context "with #{type} value" do
10
+ let(:specified_value) {
11
+ generator.call
12
+ }
13
+
14
+ let(:desired) {
15
+ # desired entry doesn't have the specified_value
16
+ {
17
+ 'sys' => { 'id' => "k#{rand}", 'contentType' => { 'sys' => { 'id' => 'test1' } } },
18
+ 'fields' => { type.to_s => { 'en-US' => 1.upto(rand(2..5)).map { generator.call } } }
19
+ }
20
+ }
21
+
22
+ let(:data) {
23
+ 1.upto(3).map do |i|
24
+ random_values = 1.upto(rand(2..5)).map { generator.call }
25
+
26
+ # remaining data does include the specified_value
27
+ {
28
+ 'sys' => {
29
+ 'id' => "k#{i}",
30
+ 'contentType' => { 'sys' => { 'id' => 'test1' } }
31
+ },
32
+ 'fields' => { type.to_s => { 'en-US' => [*random_values, specified_value].shuffle } }
33
+ }
34
+ end
35
+ }
36
+
37
+ it 'find_by can apply filter object' do
38
+ specified_value = generator.call
39
+ data = {
40
+ 'sys' => { 'id' => "k#{rand}", 'contentType' => { 'sys' => { 'id' => 'test1' } } },
41
+ 'fields' => { type.to_s => { 'en-US' => specified_value } }
42
+ }
43
+
44
+ subject.set(data.dig('sys', 'id'), data)
45
+
46
+ # act
47
+ found = subject.find_by(content_type: 'test1', filter: { type.to_s => { ne: specified_value } })
48
+
49
+ # assert
50
+ expect(found).to be_nil
51
+ end
52
+
53
+ it 'find_by can find value in array' do
54
+ [*data, desired].shuffle.each { |d| subject.set(d.dig('sys', 'id'), d) }
55
+
56
+ # act
57
+ found = subject.find_by(content_type: 'test1', filter: { type.to_s => { ne: specified_value } })
58
+
59
+ # assert
60
+ expect(found).to_not be_nil
61
+ expect(found).to eq(desired)
62
+ end
63
+
64
+ it 'find_all can apply operator' do
65
+ [*data, desired].shuffle.each { |d| subject.set(d.dig('sys', 'id'), d) }
66
+
67
+ # act
68
+ found = subject.find_all(content_type: 'test1')
69
+ .ne(type.to_s, specified_value)
70
+
71
+ # assert
72
+ expect(found.count).to eq(1)
73
+ expect(found.first).to eq(desired)
74
+ end
75
+ end
76
+ end
77
+ end
@@ -0,0 +1,80 @@
1
+ # frozen_string_literal: true
2
+
3
+ RSpec.shared_examples 'supports :nin operator' do
4
+ it 'find_all with array on string field' do
5
+ ids = 1.upto(10).to_a
6
+ data =
7
+ ids.map do |i|
8
+ {
9
+ 'sys' => {
10
+ 'id' => "k#{i}",
11
+ 'contentType' => { 'sys' => { 'id' => 'test' } }
12
+ },
13
+ 'fields' => { 'name' => { 'en-US' => "test#{i}" } }
14
+ }
15
+ end
16
+ data.each { |d| subject.set(d.dig('sys', 'id'), d) }
17
+
18
+ to_exclude = ids.shuffle.take(2)
19
+
20
+ # act
21
+ found = subject.find_all(content_type: 'test')
22
+ .nin('name', to_exclude.map { |i| "test#{i}" })
23
+
24
+ expect(found.count).to eq(8)
25
+ expect(found.map { |item| item.dig('sys', 'id') }.sort).to eq(
26
+ (ids - to_exclude).map { |i| "k#{i}" }.sort
27
+ )
28
+ end
29
+
30
+ it 'find_all with array on array field' do
31
+ ids = 1.upto(10).to_a
32
+ data =
33
+ ids.map do |i|
34
+ {
35
+ 'sys' => {
36
+ 'id' => "k#{i}",
37
+ 'contentType' => { 'sys' => { 'id' => 'test' } }
38
+ },
39
+ 'fields' => { 'name' => { 'en-US' => ["test#{i}", "test_2_#{i}"] } }
40
+ }
41
+ end
42
+ data.each { |d| subject.set(d.dig('sys', 'id'), d) }
43
+
44
+ to_exclude1, to_exclude2 = ids.shuffle
45
+
46
+ # act
47
+ found = subject.find_all(content_type: 'test')
48
+ .nin('name', ["test#{to_exclude1}", "test_2_#{to_exclude2}"])
49
+
50
+ expect(found.count).to eq(8)
51
+ expect(found.map { |item| item.dig('sys', 'id') }.sort).to eq(
52
+ (ids - [to_exclude1, to_exclude2]).map { |i| "k#{i}" }.sort
53
+ )
54
+ end
55
+
56
+ it 'find_by with array on string field' do
57
+ ids = 1.upto(2).to_a
58
+ data =
59
+ ids.map do |i|
60
+ {
61
+ 'sys' => {
62
+ 'id' => "k#{i}",
63
+ 'contentType' => { 'sys' => { 'id' => 'test' } }
64
+ },
65
+ 'fields' => { 'name' => { 'en-US' => "test#{i}" } }
66
+ }
67
+ end
68
+ data.each { |d| subject.set(d.dig('sys', 'id'), d) }
69
+
70
+ to_exclude, to_expect = ids.shuffle
71
+
72
+ # act
73
+ found = subject.find_by(
74
+ content_type: 'test',
75
+ filter: { name: { nin: ['asdf', "test#{to_exclude}"] } }
76
+ )
77
+
78
+ expect(found.dig('sys', 'id')).to eq("k#{to_expect}")
79
+ end
80
+ end
@@ -0,0 +1,50 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative './operators/eq'
4
+ require_relative './operators/ne'
5
+ require_relative './operators/in'
6
+ require_relative './operators/nin'
7
+
8
+ (WCC::Contentful::Store::Query::Interface::OPERATORS -
9
+ %i[eq ne in nin]).each do |op|
10
+ RSpec.shared_examples "supports :#{op} operator" do
11
+ it 'TODO'
12
+ end
13
+ end
14
+
15
+ RSpec.shared_examples 'operators' do |feature_set|
16
+ supported_operators =
17
+ if feature_set.nil?
18
+ WCC::Contentful::Store::Query::Interface::OPERATORS
19
+ .each_with_object({}) { |k, h| h[k] = 'pending' }
20
+ elsif feature_set.is_a?(Array)
21
+ WCC::Contentful::Store::Query::Interface::OPERATORS
22
+ .each_with_object({}) { |k, h| h[k] = feature_set.include?(k.to_sym) }
23
+ elsif feature_s.is_a?(Hash)
24
+ feature_set
25
+ else
26
+ raise ArgumentError, 'Please provide a hash or array of operators to test'
27
+ end
28
+
29
+ supported_operators.each do |op, value|
30
+ next if value
31
+
32
+ it "does not support :#{op}" do
33
+ expect {
34
+ subject.find_all(content_type: 'test')
35
+ .apply('name' => { op => 'test' })
36
+ .to_a
37
+ }.to raise_error do |ex|
38
+ expect(ex.to_s).to match(/not supported/)
39
+ end
40
+ end
41
+ end
42
+
43
+ supported_operators.each do |op, value|
44
+ next unless value
45
+
46
+ it_behaves_like "supports :#{op} operator" do
47
+ before { pending(":#{op} operator to be implemented") } if value == 'pending'
48
+ end
49
+ end
50
+ end
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require_relative './rspec_examples/basic_store'
4
+ require_relative './rspec_examples/operators'
4
5
  require_relative './rspec_examples/nested_queries'
5
6
  require_relative './rspec_examples/include_param'
6
7
 
@@ -41,6 +42,7 @@ RSpec.shared_examples 'contentful store' do |feature_set|
41
42
  }.merge(feature_set&.symbolize_keys || {})
42
43
 
43
44
  include_examples 'basic store'
45
+ include_examples 'operators', feature_set[:operators]
44
46
  include_examples 'supports nested queries', feature_set[:nested_queries]
45
47
  include_examples 'supports include param', feature_set[:include_param]
46
48
  end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module WCC
4
4
  module Contentful
5
- VERSION = '1.1.0'
5
+ VERSION = '1.1.1'
6
6
  end
7
7
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: wcc-contentful
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.0
4
+ version: 1.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Watermark Dev
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-02-02 00:00:00.000000000 Z
11
+ date: 2022-02-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: byebug
@@ -484,6 +484,11 @@ files:
484
484
  - lib/wcc/contentful/store/rspec_examples/basic_store.rb
485
485
  - lib/wcc/contentful/store/rspec_examples/include_param.rb
486
486
  - lib/wcc/contentful/store/rspec_examples/nested_queries.rb
487
+ - lib/wcc/contentful/store/rspec_examples/operators.rb
488
+ - lib/wcc/contentful/store/rspec_examples/operators/eq.rb
489
+ - lib/wcc/contentful/store/rspec_examples/operators/in.rb
490
+ - lib/wcc/contentful/store/rspec_examples/operators/ne.rb
491
+ - lib/wcc/contentful/store/rspec_examples/operators/nin.rb
487
492
  - lib/wcc/contentful/sync_engine.rb
488
493
  - lib/wcc/contentful/sys.rb
489
494
  - lib/wcc/contentful/test.rb