Skip to content

Instantly share code, notes, and snippets.

@LarrySul
Forked from tillkruss/README.md
Last active September 10, 2019 22:32
Show Gist options
  • Save LarrySul/1f323eb7e78fba0d20243794d8d11bda to your computer and use it in GitHub Desktop.
Save LarrySul/1f323eb7e78fba0d20243794d8d11bda to your computer and use it in GitHub Desktop.
Junior developer code challenge for Mercatus

Mercatus code challenge

Hi there!

Please write thorough and human-readable tests for the WaitlistController.php.

  • You can use unit, feature and/or browser tests
  • Cover corner-cases / regressions
  • The tests don't actually need run

Please email your submission in form of a link to either a fork of this gist with your test files added, or alternatively a public git repository.

Estimated time: 1 hour
Deadline: 2019-09-12T09:00:00-07:00

@extends('layouts.plain')
@section('title', 'You’re subscribed')
@section('content')
<h1 class="text-3xl font-semibold leading-tight text-center mb-3">
Hooray! You’re on the waitlist.
</h1>
<p class="text-gray-600 text-center">
In the meantime, feel free to reach out to us anytime at:
<a href="mailto:{{ config('mail.from.address') }}">{{ config('mail.from.address') }}</a>
</p>
@endsection
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Subscriber extends Model
{
protected $fillable = [
'email',
];
}
<?php
namespace App\Mail;
use App\Models\Subscriber;
use Illuminate\Bus\Queueable;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Contracts\Queue\ShouldQueue;
class SubscriberJoined extends Mailable implements ShouldQueue
{
use Queueable, SerializesModels;
public $subscriber;
public function __construct(Subscriber $subscriber)
{
$this->subscriber = $subscriber;
}
public function build()
{
return $this->markdown('emails.subscribers.joined-waitlist')
->subject('Someone joined the waitlist')
->replyTo($this->subscriber->email);
}
}
<?php
namespace Tests\Feature;
use Tests\TestCase;
use Illuminate\Foundation\Testing\RefreshDatabase;
use App\Models\Subscriber;
use App\Mail\SubscriberJoined;
use App\Waitlist;
use App\Subscriber;
use Illuminate\Support\Facades\Mail;
class SubscriberTest extends TestCase
{
//the test is used to ensure that the landing page loads correctly it returns response 200 and shows if a certain text appears. In my case I assert to see more than a text
protected $index_route = '/';
protected $store_route = '/post'
protected $subscribed_route = '/subscribed'
protected function getResponse($data)
{
return $this->jsonPost(route($this->store_route), $data);
}
public function test_it_load_information_on_the_landing_page()
{
$response = $this->get(route($this->index_route));
$response->assetStatus(200);
$response->assertSee('The marketplace');
$response->assertSee('Licensed agricultural');
}
public function test_it_validate_email_is_required()
{
$response = $this->getResponse([]);
$this->assertJsonValidationErrors(['email']);
}
public function test_it_validate_email_is_unique()
{
$registered_subscriber = factory(Subscriber::class)->create([
'email' => 'test@test.com',
]);
$response = $this->getResponse(['email' => $registered_subscriber->email]);
$this->assertJsonValidationErrors(['email']);
}
public function test_it_validate_email_is_valid()
{
$response = $this->getResponse(['email' => 'somerandommail']);
$this->assertJsonValidationErrors(['email']);
}
public function test_it_persist_subscriber_data_to_the_database()
{
$response = $this->getResponse(['email' => 'test@test.com']);
$this->assertDatabaseHas('subscribers', [
'email' => 'test@test.com'
]);
}
public function test_it_send_subscriber_mail()
{
Mail::fake();
$email = $this->faker->email;
$subscriber = factory(Subscriber::class)->create([
'email' => $email,
]);
Mail::assertSent($subscriber, function ($email) {
return $mail->hasTo($email);
});
}
public function test_it_get_redirected_to_subscribe_page_successfully()
{
$response = $this->getResponse(['email' => 'test@test.com']):
$response->assertRedirect(route($this->subscribed_route));
$this->assertSee('Hooray! You\’re on the waitlist.'):
}
}
@extends('layouts.plain')
@section('title', 'The marketplace for verified buyers and sellers.')
@section('content')
<h1 class="text-3xl font-semibold leading-tight text-center mb-3">
The marketplace for <br class="hidden lg:inline">verified buyers and sellers.
</h1>
<p class="text-gray-600 text-center mb-10">
Licensed agricultural or extracted products.
</p>
<form class="max-w-sm xl:w-5/6 mx-auto" method="POST" action="{{ route('waitlist') }}">
@csrf
<div class="form-group">
<label class="form-label" for="email">{{ __('Email Address') }}</label>
<input id="email" type="email" class="form-control @error('email') is-invalid @enderror" name="email" value="{{ old('email') }}" autocomplete="email" required>
@error('email')
<div class="invalid-feedback" role="alert">{{ $message }}</div>
@enderror
</div>
<button type="submit" class="btn btn-block btn-primary mb-3">
{{ __('Request early access') }}
</button>
<div class="text-center">
<small class="text-gray-600">
Already have an account? <a class="text-primary" href="{{ route('login') }}">Log in</a>
or <a class="text-primary" href="{{ route('register') }}">redeem your code</a>.
</small>
</div>
</form>
@endsection
<?php
namespace App\Http\Controllers;
use App\Models\Subscriber;
use App\Mail\SubscriberJoined;
use App\Http\Requests\WaitlistRequest;
use Illuminate\Support\Facades\Mail;
class WaitlistController extends Controller
{
public function index()
{
return view('waitlist');
}
public function subscribe(WaitlistRequest $request)
{
$subscriber = Subscriber::create([
'email' => $request->email,
]);
Mail::to(config('mail.from.address'))->send(
new SubscriberJoined($subscriber)
);
return redirect()->route('subscribed');
}
public function subscribed()
{
return view('subscribed');
}
}
<?php
namespace App\Http\Requests;
class WaitlistRequest extends FormRequest
{
public function filters()
{
return [
'email' => 'mb_strtolower',
];
}
public function rules()
{
return [
'email' => [
'required',
'email:strict',
'unique:subscribers'
],
];
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment