Class: Async::Caldav::Storage::Mock

Inherits:
Protocol::Caldav::Storage
  • Object
show all
Defined in:
lib/async/caldav/storage/mock.rb

Instance Method Summary collapse

Constructor Details

#initializeMock

Returns a new instance of Mock.



7
8
9
10
11
# File 'lib/async/caldav/storage/mock.rb', line 7

def initialize
  @collections = {}
  @items = {}
  @sync_snapshots = {}  # token => { collection_path => { item_path => etag } }
end

Instance Method Details

#collection_exists?(path) ⇒ Boolean

Returns:

  • (Boolean)


68
69
70
# File 'lib/async/caldav/storage/mock.rb', line 68

def collection_exists?(path)
  @collections.key?(path)
end

#create_collection(path, props = {}) ⇒ Object

--- Collections ---



15
16
17
18
19
20
21
22
23
24
25
# File 'lib/async/caldav/storage/mock.rb', line 15

def create_collection(path, props = {})
  {
    type:        props[:type] || :collection,
    displayname: props[:displayname],
    description: props[:description],
    color:       props[:color],
    props:       props[:props] || {},
  }.tap do |col|
    @collections[path] = col
  end
end

#delete_collection(path) ⇒ Object



31
32
33
34
35
36
37
38
# File 'lib/async/caldav/storage/mock.rb', line 31

def delete_collection(path)
  if @collections.delete(path)
    @items.delete_if { |k, _| k.start_with?(path) }
    true
  else
    false
  end
end

#delete_item(path) ⇒ Object



86
87
88
# File 'lib/async/caldav/storage/mock.rb', line 86

def delete_item(path)
  !!@items.delete(path)
end

#etag(path) ⇒ Object



165
166
167
168
# File 'lib/async/caldav/storage/mock.rb', line 165

def etag(path)
  item = @items[path]
  item ? item[:etag] : nil
end

#exists?(path) ⇒ Boolean

--- General ---

Returns:

  • (Boolean)


161
162
163
# File 'lib/async/caldav/storage/mock.rb', line 161

def exists?(path)
  @items.key?(path) || @collections.key?(path)
end

#get_collection(path) ⇒ Object



27
28
29
# File 'lib/async/caldav/storage/mock.rb', line 27

def get_collection(path)
  @collections[path]
end

#get_item(path) ⇒ Object

--- Items ---



74
75
76
# File 'lib/async/caldav/storage/mock.rb', line 74

def get_item(path)
  @items[path]
end

#get_multi(paths) ⇒ Object



107
108
109
# File 'lib/async/caldav/storage/mock.rb', line 107

def get_multi(paths)
  paths.map { |p| [p, @items[p]] }
end

#list_collections(parent_path) ⇒ Object



40
41
42
43
44
45
46
47
# File 'lib/async/caldav/storage/mock.rb', line 40

def list_collections(parent_path)
  if parent_path.end_with?('/')
    parent = parent_path
  else
    parent = "#{parent_path}/"
  end
  @collections.select { |k, _| direct_child?(k, parent) }.to_a
end

#list_items(collection_path) ⇒ Object



90
91
92
93
94
95
96
97
# File 'lib/async/caldav/storage/mock.rb', line 90

def list_items(collection_path)
  if collection_path.end_with?('/')
    prefix = collection_path
  else
    prefix = "#{collection_path}/"
  end
  @items.select { |k, _| k.start_with?(prefix) && k != collection_path }.to_a
end

#move_item(from_path, to_path) ⇒ Object



99
100
101
102
103
104
105
# File 'lib/async/caldav/storage/mock.rb', line 99

def move_item(from_path, to_path)
  item = @items.delete(from_path)
  if item
    @items[to_path] = item
    item
  end
end

#put_item(path, body, content_type) ⇒ Object



78
79
80
81
82
83
84
# File 'lib/async/caldav/storage/mock.rb', line 78

def put_item(path, body, content_type)
  etag = Protocol::Caldav::ETag.compute(body)
  is_new = !@items.key?(path)
  item = { body: body, content_type: content_type, etag: etag }
  @items[path] = item
  [item, is_new]
end

#snapshot_sync(collection_path) ⇒ Object

--- Sync ---



113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
# File 'lib/async/caldav/storage/mock.rb', line 113

def snapshot_sync(collection_path)
  items = list_items(collection_path)
  snapshot = {}
  items.each { |path, data| snapshot[path] = data[:etag] }

  # Compute a token from the current state
  item_etags = items.map { |_, data| data[:etag] }
  col = @collections[collection_path] || {}
  ctag = Protocol::Caldav::CTag.compute(
    path:        collection_path,
    displayname: col[:displayname],
    description: col[:description],
    color:       col[:color],
    item_etags:  item_etags,
  )
  token = "http://caldav.local/sync/#{ctag}"

  @sync_snapshots[token] = { collection_path => snapshot }
  token
end

#sync_changes(collection_path, token) ⇒ Object



134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
# File 'lib/async/caldav/storage/mock.rb', line 134

def sync_changes(collection_path, token)
  old_snapshot_entry = @sync_snapshots[token]
  if old_snapshot_entry
    old_snapshot = old_snapshot_entry[collection_path] || {}
    new_token = snapshot_sync(collection_path)
    current_items = list_items(collection_path)
    current = {}
    current_items.each { |path, data| current[path] = data[:etag] }
    changes = []
    current.each do |path, etag|
      if !old_snapshot.key?(path) || old_snapshot[path] != etag
        changes << [path, :modified]
      end
    end
    old_snapshot.each_key do |path|
      unless current.key?(path)
        changes << [path, :deleted]
      end
    end
    [new_token, changes]
  else
    nil
  end
end

#update_collection(path, props) ⇒ Object



49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
# File 'lib/async/caldav/storage/mock.rb', line 49

def update_collection(path, props)
  col = @collections[path]
  if col
    if props.key?(:displayname)
      col[:displayname] = props[:displayname]
    end
    if props.key?(:description)
      col[:description] = props[:description]
    end
    if props.key?(:color)
      col[:color] = props[:color]
    end
    if props.key?(:props)
      col[:props] = (col[:props] || {}).merge(props[:props])
    end
    col
  end
end