SteveAzz's avatar

How should I write this test

So I have two database tables with a many to many relationship. One of them is Item and the other one it Tier.

I have a form which takes the name of the new Item and the Tier id or if he enters a string it will create the new tier and save it to the database.

For example the user enters "Photo" as the item name, and enters "Gold" as a new tier which doesn't exsist. This is the same as "Many to Many Relations (With Tags) " in the laravel 5 fundementals series here on laracasts.

How to come about testing this? I know my code works because I tried it on the browser and works but i want to create tests for it, now I know that first you need to write the test first and then the code but bear with me please :)

The following is what I did

$item = TestDummy::create('App\Item');

        $this->user_log_in();

        $this->visit('items/create')
            ->type($item->name, 'name')
            ->type('Gold', 'tier_list')
            ->press('Create new Item')
            ->verifyInDatabase('items', $item);

When I run this test it gives me the following error Input "tier_list" cannot take "Gold" as a value (possible values: ).

0 likes
5 replies
bastiaan89's avatar

The tier_list input field is probably a select. Your text input field probably has a different name?

SteveAzz's avatar

@bastiaan89 No same field but in chrome when i enter "Gold" and it doesn't exists it just creates it.

bastiaan89's avatar

So it is a single text field where you can either enter an existing ID or a new name? Could you share the back end code that handles this form?

Also, I see you're creating a new item with TestDummy but then creating another item with the same name through that form? If you just need dummy attributes use TestDummy::attributesFor().

SteveAzz's avatar

My back end code is the following

public function store(ItemRequest $request)
    {
        $this->createItem($request);

        flash()->success('You have created the item successfully');

        return redirect('dashboard/items');
    }
private function createItem(ItemRequest $request)
    {
        $item = Item::create($request->all());

        $this->syncTiers($item, $request->input('tier_list'));
    }
 private function syncTiers(Item $item, array $tier_list)
    {
        $tier_ids = array_filter($tier_list, 'is_numeric');
        $new_tiers = array_diff($tier_list, $tier_ids);

        foreach ($new_tiers as $new_tier) {
            Tier::create(['name' => $new_tier]);
            $tier_ids[] = Tier::where(['name' => $new_tier])->pluck('id');
        }

        $item->tiers()->sync($tier_ids);
    }

Please or to participate in this conversation.