1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
# frozen_string_literal: true
require_relative "test_helper"
require "minitest/autorun"
require_relative "../lib/rank_king/sync"
class TestSync < Minitest::Test
include RankKing
# A synced source that keeps each item's key in memory, standing in for a
# source that keeps its keys in its own table keyed by item_id.
class FakeSource
attr_reader :calls
def initialize
@keys = {}
@calls = []
end
def items_by_key = @keys.transform_values {|id| RankKing::Item[id] }
def saved(item, entry)
@keys[entry.key] = item.id
@calls << [item.id, entry.key]
end
end
def setup
DB[:results].delete
DB[:axes].delete
DB[:items].delete
DB[:lists].delete
DB[:users].delete
user = User.create(login: "alpha@example.com")
@list = List.create(name: "Videos", user_id: user.id, source_kind: "Fake")
@source = FakeSource.new
end
def test_adds_new_entries
summary = sync("a", "b")
assert_equal Sync::Summary.new(added: 2, restored: 0, archived: 0), summary
assert_equal %w[a b], names
refute_nil @list.reload.synced_at
end
def test_archives_missing_entries_and_keeps_their_rows
sync("a", "b")
summary = sync("a")
assert_equal 1, summary.archived
assert_equal %w[a], names
refute_nil Item.first(name: "b").archived_at
end
def test_restores_entries_that_come_back
sync("a", "b")
b = Item.first(name: "b")
sync("a")
summary = sync("a", "b")
assert_equal 1, summary.restored
assert_equal [b.id], Item.where(name: "b").map(:id)
assert_equal %w[a b], names
end
def test_refreshes_names_and_tells_the_source
sync("a")
item = Item.first
Sync.call(@list, [entry("a", name: "Renamed")], source: @source)
assert_equal "Renamed", item.reload.name
assert_equal [[item.id, "a"]] * 2, @source.calls
end
private
def entry(key, name: key)
Sources::Entry.new(key:, name:)
end
def sync(*keys) = Sync.call(@list, keys.map {|key| entry(key) }, source: @source)
def names = @list.items_dataset.order(:id).map(:name)
end