@@ -174,6 +174,46 @@ func TestPersistRemove(t *testing.T) {
174174 }
175175}
176176
177+ // TestPersistDirectoryOnlyAdds covers the case where every Add() to a node
178+ // carries an empty entry (only forks/metadata), so the lazy-init in Add()
179+ // never sets refBytesSize. Without the marshal-time inference, the header
180+ // would report refBytesSize=0 even though the children have full-width refs,
181+ // and the v0.2 reader would silently drop every fork.
182+ func TestPersistDirectoryOnlyAdds (t * testing.T ) {
183+ t .Parallel ()
184+
185+ ctx := context .Background ()
186+ ls := mantaray .LoadSaver (newMockLoadSaver ())
187+
188+ n := mantaray .New ()
189+ n .SetObfuscationKey (mantaray .ZeroObfuscationKey )
190+
191+ paths := [][]byte {[]byte ("foo" ), []byte ("bar" ), []byte ("baz" )}
192+ for _ , p := range paths {
193+ // empty entry; only metadata. Mirrors bee/pkg/api/bzz.go:266 which
194+ // adds the root path with swarm.ZeroAddress (a nil []byte).
195+ if err := n .Add (ctx , p , nil , map [string ]string {"k" : "v" }, ls ); err != nil {
196+ t .Fatalf ("add %q: %v" , p , err )
197+ }
198+ }
199+
200+ if err := n .Save (ctx , ls ); err != nil {
201+ t .Fatalf ("save: %v" , err )
202+ }
203+ ref := n .Reference ()
204+
205+ nn := mantaray .NewNodeRef (ref )
206+ for _ , p := range paths {
207+ ln , err := nn .LookupNode (ctx , p , ls )
208+ if err != nil {
209+ t .Fatalf ("lookup %q: %v" , p , err )
210+ }
211+ if v := ln .Metadata ()["k" ]; v != "v" {
212+ t .Fatalf ("lookup %q: expected metadata k=v, got %q" , p , v )
213+ }
214+ }
215+ }
216+
177217type (
178218 addr [32 ]byte
179219 mockLoadSaver struct {
0 commit comments