BuildInPublic

After a lot of other stuff I’m back at it. TIL that php ENUMS are kind of hard to do assertions on in PHPUnit. assertSame and assertEquals both don’t work.

What I can do though is this:

$this->assertSame(SyncStatus::Pending->value, $syncStatusAfter->value);

#buildinpublic #mbsync

After many hours of familystuff, I’m back trying to see why one of the tests is still failing, now that my sidequest about the seeder is complete. #buildinpublic #mbsync

[Just noticed I never sent this…]

#buildinpublic #mbsync

Alright, so the seeder works and I can skip registering all the time when resetting the db. 😅

Instead I only need to run:

artisan migrate:fresh

and then:

artisan db:seed

And I’m good to go!

The code needed some trial and error to get right, but looks basically like this:

<?php

namespace Database\Seeders;

use App\Models\Blog;
use App\Models\User;
use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\Config;
use Illuminate\Support\Facades\Hash;

class AddAdminUserSeeder extends Seeder
{
    public function run(): void
    {
        $user = User::create([
		//...
        ]);
        $user->save();
        $blogs = [
		//...
        ];
        $user->blogs()->saveMany($blogs);
        $user->selected_blog_id = $blogs[0]->id;
        $user->save();
    }
}

It’s just really cool to me how powerful laravel’s db abstractions are. I may not know yet how to express my needs and then try to do it old-school directly in sql at first, but that it’s possible to express my needs and I can otherwise just focus on the code is so cool. #buildinpublic #mbsync

I’m working on a little side quest atm. I’m creating a database seeder that automatically adds a user to the db so that I can reset the db quicker. It’s pretty easy with laravel and I love the distinction between migrations (schema changes) and seeders (data additions) #buildinpublic #mbsync

At the moment I’m working on implementing the minimalistic sync engine - even calling it that gives it too much credit. One test is failing, it seems that the sync status is not marked as pending when we mark a post for sync. #buildinpublic #mbsync

I’ll continue my work on mb-sync. It’s always a little hard to know how much time I have - so I might need to do something else soon, but I’ll at least start. #buildinpublic #mbsync

#buildinpublic #zknstuff The library is closing soon and I’m spent mentally for the moment. Time to take the rest of the Sunday off!

#buildinpublic #zknstuff I did it. Around 200 notes have been reviewed, filed away, linked to and from, some of them tagged, renamed, deleted (very few). Most of them were how-to notes, some were ideas, some were project journals, some just held some information like an address, a measurement, etc.

#buildinpublic #zknstuff Still 66 files to go. An observation: I need to do focussed reviews, that is, reviews that only tackle part of the system, more often. That I can review files in this way is actually very helpful to make those notes I took time to write more useful and discoverable.

#buildinpublic #zknstuff Still 136 Files to review in my Inbox and I might not do anything else after this, actually, since this is going to take a moment still. But I’m very happy that the simple note review plugin works now as expected.

#buildinpublic #zknstuff I think that either simple note review or the underlying dataview plugin got a fix, because it now actually works as expected?! I’m reviewing, moving and lightly editing the notes in my Inbox folder and try to think a little how to review my readwise highlights next.

#buildinpublic #zknstuff Even though I had abandoned the simple note review plugin since it didn’t work very well and the spaced repetition plugin seemed more stable I have now reverted to the former. Main reason: Having different review queues, since having just one giant queue didn’t cut it.

#buildinpublic #zknstuff I’m trying to figure out how to use these library Sundays the best at the moment and my idea was to use the spaced repetition plugin for it. I have done that a handful of weeks now but with so many notes it is kind of unsatisfying. So let’s think about the review process a little, cleaning up what is there and maybe finding a new way to do things.

Today I’m spending time in the library working on my notes. I thought I’d try to do a #buildinpublic kind of thing, since it was fun the last couple of days to post about what I’m doing as regards to #mbsync. so I’m going to try this here, too. Hashtags will be #buildinpublic and #zknstuff.

#buildinpublic #mbsync That’s it for today. Lots of little things done. Learned some stuff and realized a lot of things about how to structure the sync state. This’ll be the most important part of the app, so it’s alright if it takes some time and some attempts to get right.

(Last updated: )

#buildinpublic #mbsync Alright. The test for a post that is unchanged does the thing and I already created a similar test for a newly created post. However I don’t like how the sync status is saved in the db. Or rather how different kinds of logic are reduced to only the sync state. We need to differentiate between the state of the sync itself (pending/synchronized/error) and what we sync (creation/update/deletion). At least I think it’d be nice to be explicit about it. Makes it more testable. So we need two fields in the db on every post:

  • sync_status: pending, synchronized, error, none
  • sync_intention: create, update, delete, none

#buildinpublic #mbsync So. Me the last few hours:

I’m not distracted, I’m on a side quest. — https://beige.party/@RickiTarr/112264314660393539

Where was I? Oh yes. Refactoring/Writing a test for the markForSync method. I have the starting point for the test, which creates a post using a factory and writes that same data to disk. Now we need to run the post through our method and see that the posts sync_status is not marked for creation/update/deletion.

#buildinpublic #mbsync Ugh. And even more problems. I use the laravel validated dto package, because I like working with DTOs and getting validation “for free” is nice. However:

If a post doesn’t have a category the mb api returns an empty array. Fine. I can validate this as 'categories' => ['present', 'array'],, but interestingly the DTOs saves this internally as null. And guess what? categories in not nullable anymore when I try to save a post with empty categories to the db. Hmpf.

#buildinpublic #mbsync Discoverd another problem: I was allowing the categories field (json in the db) in my Post model to be null. Turns out if you do that you can’t cast that json to array through eloquent. So I changed that in my migrations, but this means that the assumption you can write a post to the db with categories being null doesn’t hold anymore. So more yak shaving…

#buildinpublic #mbsync I’m much more familiar with codeception and my brain is kinda mushy so figuring out how to do things in PHPUnit took its time. However, I refactored that storePost method now and have a test (which I wrote first or at least started to write first) to make sure it does what I want it to do. Now back to testMarkForSync.

(Last updated: )

#buildinpublic #mbsync After a late combined breakfast/lunch back at it. Still writing the testcase for storePost. I had to think about how to structure tests that rely on test data or rather needs a directory to write to. I generally like to mirror the structure of the app in my tests, so that I can find the things I need easily. I have now introduced a testData directory where I can write to/from the filesystem. It looks like this:

#buildinpublic #mbsync Well, that worked. We just had to add:

public function posts(): \Illuminate\Database\Eloquent\Relations\HasMany
    {
        return $this->hasMany(Post::class);
    }

to the Blog model.

Now we can do the following in our test:

$blog = Blog::factory()->has(Post::factory()->count(1))->create();
$post = $blog->posts->first();

That post now has some fake data as defined in my PostFactory.

Time to write this to disk. We could use PostFilePersistorService::storePost. This method makes a couple of assumptions about where to write data and I would like it to just write where I want it to. So I will refactor the path generation logic out of storePost. In the future it should be handed in via a parameter. This is a big change but we’re the only developer and in the “break lots of things” phase, so I feel this is fine.

There is only one problem: We again have no test! So what I’ll do is make the other test pass, add a TODO to it and create a test for storePost. First things first.

#buildinpublic #mbsync Well, it seems that my models are incomplete. I am missing a relationship between a blog and its posts. This is needed so that my factory can create some posts to test with.

#buildinpublic #mbsync No tests, alright. What do we want to test here? If we call markForSync() a changed post, a deleted post, a new post and an unchanged post should all be detected correctly. So let’s start with the simple case that a post in the db and in the filesystem are the same.