Skip to content

Commit

Permalink
Show flash message for click creation
Browse files Browse the repository at this point in the history
  • Loading branch information
ledermann committed Oct 23, 2022
1 parent 919f2f5 commit 381d3c8
Show file tree
Hide file tree
Showing 9 changed files with 68 additions and 22 deletions.
3 changes: 3 additions & 0 deletions .rubocop.yml
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,9 @@ Style/StringLiteralsInInterpolation:
Metrics/BlockLength:
Max: 100

Metrics/MethodLength:
Max: 15

# Lint

Lint/ConstantResolution:
Expand Down
14 changes: 7 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ https://github.com/rails/rails/pull/41994

### JavaScript size

152 KB of compiled JavaScript (after tree-shaking, minified & uncompressed). The largest parts are:
154 KB of compiled JavaScript (after tree-shaking, minified & uncompressed). The largest parts are:

- Vue.js + Vue Router (75 KB)
- Honeybadger (23 KB)
Expand All @@ -120,16 +120,16 @@ success Already up-to-date.
Building with Vite ⚡️
vite v3.1.8 building for production...
transforming...
368 modules transformed.
665 modules transformed.
rendering chunks...
../../public/vite/assets/logo.44ced38d.svg 0.48 KiB
../../public/vite/manifest-assets.json 0.10 KiB
../../public/vite/manifest.json 0.56 KiB
../../public/vite/assets/application.a07ce41d.js 16.15 KiB / gzip: 6.55 KiB
../../public/vite/assets/application.a07ce41d.js.map 27.97 KiB
../../public/vite/assets/application.d0868fcd.css 20.33 KiB / gzip: 4.68 KiB
../../public/vite/assets/vendor.28ca271d.js 135.98 KiB / gzip: 50.33 KiB
../../public/vite/assets/vendor.28ca271d.js.map 1039.36 KiB
../../public/vite/assets/application.a90a3d86.js 17.57 KiB / gzip: 6.96 KiB
../../public/vite/assets/application.a90a3d86.js.map 32.05 KiB
../../public/vite/assets/application.b8dceff6.css 21.70 KiB / gzip: 4.89 KiB
../../public/vite/assets/vendor.dd9ac15e.js 136.75 KiB / gzip: 50.55 KiB
../../public/vite/assets/vendor.dd9ac15e.js.map 1040.48 KiB
Build with Vite complete: /Users/ledermann/Projects/templatus-vue/public/vite
```

Expand Down
10 changes: 10 additions & 0 deletions app/controllers/clicks_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,16 @@ def create
Click.create! user_agent: request.user_agent,
ip: anonymize(request.remote_ip)
ActionCable.server.broadcast 'clicks_channel', click

render json: {
notice: 'Click was successfully recorded.',
},
status: :created
rescue StandardError
render json: {
alert: 'Click recording failed!',
},
status: :unprocessable_entity
end

private
Expand Down
4 changes: 2 additions & 2 deletions app/javascript/src/stores/click.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { defineStore } from 'pinia';
import { createConsumer, Subscription } from '@rails/actioncable';
import { get, post } from '@rails/request.js';
import { get, post } from '@/use/fetch';

export type Click = {
id: number;
Expand All @@ -21,7 +21,7 @@ export const useClickStore = defineStore('click', {

actions: {
sendClick() {
post('/clicks');
post('/clicks', { responseKind: 'json' });
},

async getClicks() {
Expand Down
1 change: 1 addition & 0 deletions spec/cypress/integration/basic.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,5 +19,6 @@ describe('Basic tests', () => {
cy.get('#counter').should('contain', '1');
cy.get('ul').should('contain', '127.0.0.0');
cy.get('li').should('have.length', 1);
cy.get('#flash').should('contain', 'successfully');
});
});
21 changes: 14 additions & 7 deletions spec/javascript/src/App.test.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { mount } from '@vue/test-utils';
import { setActivePinia, createPinia } from 'pinia';
import { createRouter, createWebHistory } from 'vue-router';

import App from '@/App.vue';

import { createRouter, createWebHistory } from 'vue-router';

const router = createRouter({
history: createWebHistory(),
routes: [
Expand All @@ -19,13 +19,20 @@ const router = createRouter({
});

describe('App', () => {
const wrapper = mount(App, {
global: {
plugins: [router],
},
// eslint-disable-next-line @typescript-eslint/no-explicit-any
let wrapper: any;

beforeEach(() => {
setActivePinia(createPinia());

wrapper = mount(App, {
global: {
plugins: [router],
},
});
});

afterAll(() => {
afterEach(() => {
wrapper.unmount();
});

Expand Down
9 changes: 7 additions & 2 deletions spec/javascript/src/__snapshots__/App.test.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,14 @@ exports[`App matches snapshot 1`] = `
<polygon fill="url(#grad2)" points="0,80 0,100 100,100 100,50"></polygon>
</svg>
<header class="flex items-end justify-between space-x-5 p-5 lg:flex-col lg:items-stretch lg:space-y-36 lg:space-x-0 lg:p-0 lg:fixed lg:top-10 lg:left-10"><img src="[object Object]" alt="Logo" class="h-20 w-20 rounded bg-gradient-to-br from-slate-200 to-white p-3 lg:h-56 lg:w-56" width="150" height="150">
<nav class="flex space-x-5 text-center text-lg font-medium uppercase lg:flex-col lg:space-y-5 lg:space-x-0"><a href="/" class="router-link-active router-link-exact-active bg-white text-rails-dark lg:bg-rails-dark lg:text-white rounded-md px-2 py-1 transition lg:shadow" aria-current="page">Home</a><a href="/about" class="bg-transparent text-white hover:scale-105 lg:bg-white lg:text-rails-dark rounded-md px-2 py-1 transition lg:shadow">About</a></nav>
<nav class="flex space-x-5 text-center text-lg font-medium uppercase lg:flex-col lg:space-y-5 lg:space-x-0"><a href="/" class="bg-white text-rails-dark lg:bg-rails-dark lg:text-white rounded-md px-2 py-1 transition lg:shadow">Home</a><a href="/about" class="bg-transparent text-white hover:scale-105 lg:bg-white lg:text-rails-dark rounded-md px-2 py-1 transition lg:shadow">About</a></nav>
</header>
<main class="relative flex-1 bg-white py-5 px-4 shadow-md sm:px-6 lg:mt-10 lg:mr-16 lg:ml-96 lg:max-w-5xl lg:rounded-xl lg:px-8">Home page</main>
<transition-stub mode="out-in" enteractiveclass="transition duration-500 ease-out" enterfromclass="translate-y-32" entertoclass="translate-y-0" leaveactiveclass="transition duration-500 ease-in" leavefromclass="translate-y-0" leavetoclass="translate-y-32" appear="false" persisted="false" css="true">
<!--v-if-->
</transition-stub>
<main class="relative flex-1 bg-white py-5 px-4 shadow-md sm:px-6 lg:mt-10 lg:mr-16 lg:ml-96 lg:max-w-5xl lg:rounded-xl lg:px-8">
<!---->
</main>
<footer class="flex flex-wrap items-end justify-between space-y-2 px-4 text-sm text-white sm:px-6 lg:px-0 relative mt-2 mb-6 lg:mr-16 lg:ml-96 lg:max-w-5xl lg:px-0">
<div class="flex w-full items-end space-x-2 sm:w-auto"><a class="hover:underline" target="_blank" rel="noopener noreferrer" href="https://github.com/templatus/templatus-vue"><svg viewBox="0 0 24 24" class="h-6 w-6" fill="currentColor">
<title>GitHub</title>
Expand Down
2 changes: 1 addition & 1 deletion spec/javascript/src/stores/click.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ const mockGet = jest.fn().mockResolvedValue({

const mockPost = jest.fn().mockResolvedValue(43);

jest.mock('@rails/request.js', () => ({
jest.mock('@/use/fetch', () => ({
__esModule: true,
get: mockGet,
post: mockPost,
Expand Down
26 changes: 23 additions & 3 deletions spec/requests/clicks_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,6 @@ def call(ip)
REMOTE_ADDR: ip,
ACCEPT: 'application/json',
}

expect(response).to have_http_status(:no_content)
expect(Click.last.user_agent).to eq(user_agent)
end

context 'when IPv4' do
Expand All @@ -25,7 +22,12 @@ def call(ip)
it 'saves click' do
call(ipv4)

expect(response).to have_http_status(:created)
expect(JSON.parse(response.body)).to include(
{ 'notice' => 'Click was successfully recorded.' },
)
expect(Click.last.ip).to eq('1.2.3.0')
expect(Click.last.user_agent).to eq(user_agent)
end
end

Expand All @@ -35,7 +37,25 @@ def call(ip)
it 'saves click' do
call(ipv6)

expect(response).to have_http_status(:created)
expect(JSON.parse(response.body)).to include(
{ 'notice' => 'Click was successfully recorded.' },
)
expect(Click.last.ip).to eq('2001:0db8:0:0:0:0:0:0')
expect(Click.last.user_agent).to eq(user_agent)
end
end

context 'when saving fails' do
let(:ipv6) { 'invalid' }

it 'fails and returns http failure' do
call(ipv6)

expect(response).to have_http_status(:unprocessable_entity)
expect(JSON.parse(response.body)).to include(
{ 'alert' => 'Click recording failed!' },
)
end
end
end
Expand Down

0 comments on commit 381d3c8

Please sign in to comment.