|
50 | 50 | model_class.new(name: "Test", email: "test@test.com") |
51 | 51 | end |
52 | 52 |
|
53 | | - it "allows sending a model" do |
54 | | - expect(described_class::Build(contract: CreateForm, model_key: :model).call({ model: model })).to eq true |
| 53 | + it "defaults to state[:model] when present" do |
| 54 | + expect(described_class::Build(contract: CreateForm).call({ model: model })).to eq true |
| 55 | + end |
| 56 | + |
| 57 | + it "pre-populates form attributes from the model" do |
| 58 | + state = { model: model } |
| 59 | + described_class::Build(contract: CreateForm).call(state) |
| 60 | + expect(state[:contract].name).to eq "Test" |
| 61 | + end |
| 62 | + |
| 63 | + it "builds without a model when state[:model] is absent" do |
| 64 | + state = {} |
| 65 | + described_class::Build(contract: CreateForm).call(state) |
| 66 | + expect(state[:contract]).to be_a CreateForm |
55 | 67 | end |
56 | 68 |
|
57 | 69 | it "allows specifying the model key" do |
58 | 70 | expect(described_class::Build(contract: CreateForm, model_key: :different_model).call({ different_model: model })).to eq true |
59 | 71 | end |
60 | 72 |
|
61 | | - it "ensures the model quacks like an Active Model" do |
| 73 | + it "raises when the model key is present in state but nil" do |
| 74 | + expect { |
| 75 | + described_class::Build(contract: CreateForm).call({ model: nil }) |
| 76 | + }.to raise_error Operational::InvalidContractModel |
| 77 | + end |
| 78 | + |
| 79 | + it "raises when the model does not quack like an Active Model" do |
62 | 80 | expect { |
63 | | - described_class::Build(contract: CreateForm, model_key: :invalid).call({ model: model }) |
| 81 | + described_class::Build(contract: CreateForm).call({ model: "not a model" }) |
64 | 82 | }.to raise_error Operational::InvalidContractModel |
65 | 83 | end |
66 | 84 | end |
| 85 | + |
| 86 | + describe "model_persisted" do |
| 87 | + let(:model) { model_class.new(name: "Test") } |
| 88 | + |
| 89 | + it "overrides persisted? on the form" do |
| 90 | + state = { model: model } |
| 91 | + described_class::Build(contract: CreateForm, model_persisted: true).call(state) |
| 92 | + expect(state[:contract].persisted?).to eq true |
| 93 | + end |
| 94 | + end |
| 95 | + |
| 96 | + describe "build_method" do |
| 97 | + it "calls a custom build_method during build" do |
| 98 | + form_class = Class.new(Operational::Form) do |
| 99 | + attribute :name, :string |
| 100 | + def custom_build(state) |
| 101 | + self.name = "from custom build" |
| 102 | + end |
| 103 | + end |
| 104 | + state = {} |
| 105 | + described_class::Build(contract: form_class, build_method: :custom_build).call(state) |
| 106 | + expect(state[:contract].name).to eq "from custom build" |
| 107 | + end |
| 108 | + end |
67 | 109 | end |
68 | 110 |
|
69 | 111 | describe ".Validate" do |
|
143 | 185 |
|
144 | 186 | let(:state) { { model: model, params: { name: "update", email: "update@test.com" }} } |
145 | 187 |
|
146 | | - it "allows sending a model" do |
147 | | - described_class::Build(contract: CreateForm, model_key: :model).call(state) |
| 188 | + it "defaults to state[:model] when present" do |
| 189 | + described_class::Build(contract: CreateForm).call(state) |
148 | 190 |
|
149 | | - expect(described_class::Sync(model_key: :model).call(state)).to eq true |
| 191 | + expect(described_class::Sync().call(state)).to eq true |
150 | 192 | end |
151 | 193 |
|
152 | | - it "ensures the model quacks like an Active Model" do |
| 194 | + it "writes form attributes back to the model" do |
| 195 | + described_class::Build(contract: CreateForm).call(state) |
| 196 | + described_class::Validate().call(state) |
| 197 | + described_class::Sync().call(state) |
| 198 | + expect(model.name).to eq "update" |
| 199 | + end |
| 200 | + |
| 201 | + it "syncs without a model when state[:model] is absent" do |
| 202 | + state = { params: { name: "update" } } |
| 203 | + described_class::Build(contract: CreateForm).call(state) |
| 204 | + |
| 205 | + expect(described_class::Sync().call(state)).to eq true |
| 206 | + end |
| 207 | + |
| 208 | + it "allows specifying the model key" do |
| 209 | + state = { different_model: model, params: { name: "update" } } |
| 210 | + described_class::Build(contract: CreateForm, model_key: :different_model).call(state) |
| 211 | + described_class::Validate().call(state) |
| 212 | + described_class::Sync(model_key: :different_model).call(state) |
| 213 | + expect(model.name).to eq "update" |
| 214 | + end |
| 215 | + |
| 216 | + it "raises when the model key is present in state but nil" do |
153 | 217 | expect { |
154 | | - described_class::Sync(model_key: :invalid).call(state) |
| 218 | + described_class::Sync().call(state.merge(model: nil)) |
155 | 219 | }.to raise_error Operational::InvalidContractModel |
156 | 220 | end |
| 221 | + |
| 222 | + it "raises when the model does not quack like an Active Model" do |
| 223 | + expect { |
| 224 | + described_class::Sync().call(state.merge(model: "not a model")) |
| 225 | + }.to raise_error Operational::InvalidContractModel |
| 226 | + end |
| 227 | + |
| 228 | + describe "sync_method" do |
| 229 | + it "calls a custom sync_method during sync" do |
| 230 | + form_class = Class.new(Operational::Form) do |
| 231 | + attribute :name, :string |
| 232 | + def custom_sync(state) |
| 233 | + state[:model].email = "synced@test.com" |
| 234 | + end |
| 235 | + end |
| 236 | + state = { model: model, params: { name: "update" } } |
| 237 | + described_class::Build(contract: form_class).call(state) |
| 238 | + described_class::Validate().call(state) |
| 239 | + described_class::Sync(sync_method: :custom_sync).call(state) |
| 240 | + expect(model.email).to eq "synced@test.com" |
| 241 | + end |
| 242 | + end |
157 | 243 | end |
158 | 244 | end |
159 | 245 | end |
0 commit comments