avatarQuinn Oaks

Free AI web copilot to create summaries, insights and extended knowledge, download it at here

8645

Abstract

<span class="hljs-keyword">async</span> <span class="hljs-title function_">delete</span>(<span class="hljs-attr">id</span>: <span class="hljs-built_in">string</span>): <span class="hljs-title class_">Promise</span><<span class="hljs-title class_">Item</span>> { <span class="hljs-keyword">const</span> item = <span class="hljs-keyword">await</span> <span class="hljs-variable language_">this</span>.<span class="hljs-property">itemModel</span>.<span class="hljs-title function_">findByIdAndRemove</span>(id); <span class="hljs-keyword">if</span> (!item) { <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">NotFoundException</span>(<span class="hljs-string">'Item not found'</span>); } <span class="hljs-keyword">return</span> item; } }</pre></div><p id="61ef">3. Controller with Validation:</p><p id="425a">Inside <code>item.controller.ts</code>:</p><div id="dace"><pre><span class="hljs-keyword">import</span> { Body, Controller, Get, Post, Put, Delete, Param, NotFoundException, BadRequestException, ParseUUIDPipe } from <span class="hljs-string">'@nestjs/common'</span>; <span class="hljs-keyword">import</span> { CreateItemDto } from <span class="hljs-string">'./create-item.dto'</span>; <span class="hljs-keyword">import</span> { UpdateItemDto } from <span class="hljs-string">'./update-item.dto'</span>; <span class="hljs-keyword">import</span> { ItemService } from <span class="hljs-string">'./item.service'</span>; <span class="hljs-keyword">import</span> { Item } from <span class="hljs-string">'./item.schema'</span>;

<span class="hljs-meta">@Controller(<span class="hljs-string">'items'</span>)</span> export <span class="hljs-keyword">class</span> <span class="hljs-title class_">ItemController</span> { <span class="hljs-keyword">constructor</span>(<span class="hljs-keyword">private</span> readonly itemService: ItemService) { }

<span class="hljs-meta">@Post()</span>
async create(<span class="hljs-meta">@Body()</span> createItemDto: CreateItemDto): Promise&lt;Item&gt; {
    <span class="hljs-keyword">return</span> <span class="hljs-keyword">this</span>.itemService.create(createItemDto);
}

<span class="hljs-meta">@Get()</span>
async findAll(): Promise&lt;Item[]&gt; {
    <span class="hljs-keyword">return</span> <span class="hljs-keyword">this</span>.itemService.findAll();
}

<span class="hljs-meta">@Get(<span class="hljs-string">':id'</span>)</span>
async findOne(<span class="hljs-meta">@Param(<span class="hljs-string">'id'</span>)</span> id: string): Promise&lt;Item&gt; {
    <span class="hljs-keyword">return</span> <span class="hljs-keyword">this</span>.itemService.findOne(id);
}

<span class="hljs-meta">@Put(<span class="hljs-string">':id'</span>)</span>
async update(<span class="hljs-meta">@Param(<span class="hljs-string">'id'</span>)</span> id: string, <span class="hljs-meta">@Body()</span> updateItemDto: UpdateItemDto): Promise&lt;Item&gt; {
    <span class="hljs-keyword">return</span> <span class="hljs-keyword">this</span>.itemService.update(id, updateItemDto);
}

<span class="hljs-meta">@Delete(<span class="hljs-string">':id'</span>)</span>
async delete(<span class="hljs-meta">@Param(<span class="hljs-string">'id'</span>)</span> id: string): Promise&lt;Item&gt; {
    <span class="hljs-keyword">return</span> <span class="hljs-keyword">this</span>.itemService.delete(id);
}

}</pre></div><p id="7771">4. Activate auto-validation:</p><p id="61fc">update the fille main.ts</p><div id="fe08"><pre><span class="hljs-keyword">import</span> { <span class="hljs-title class_">NestFactory</span> } <span class="hljs-keyword">from</span> <span class="hljs-string">'@nestjs/core'</span>; <span class="hljs-keyword">import</span> { <span class="hljs-title class_">AppModule</span> } <span class="hljs-keyword">from</span> <span class="hljs-string">'./app.module'</span>; <span class="hljs-keyword">import</span> { <span class="hljs-title class_">ValidationPipe</span> } <span class="hljs-keyword">from</span> <span class="hljs-string">'@nestjs/common'</span>;

<span class="hljs-keyword">async</span> <span class="hljs-keyword">function</span> <span class="hljs-title function_">bootstrap</span>(<span class="hljs-params"></span>) { <span class="hljs-keyword">const</span> app = <span class="hljs-keyword">await</span> <span class="hljs-title class_">NestFactory</span>.<span class="hljs-title function_">create</span>(<span class="hljs-title class_">AppModule</span>); app.<span class="hljs-title function_">useGlobalPipes</span>(<span class="hljs-keyword">new</span> <span class="hljs-title class_">ValidationPipe</span>()); <span class="hljs-keyword">await</span> app.<span class="hljs-title function_">listen</span>(<span class="hljs-number">3000</span>); } <span class="hljs-title function_">bootstrap</span>();</pre></div><h1 id="a2cc">Unit Testing:</h1><p id="0fac">1. Setup:</p><p id="23ed">Install required packages:</p><div id="89f0"><pre>npm install @nestjs/testing</pre></div><p id="2a92">2. Testing the Service:</p><p id="bc15">In the <code>item.service.spec.ts</code>:</p><div id="b87f"><pre><span class="hljs-keyword">import</span> { Test, TestingModule } from <span class="hljs-string">'@nestjs/testing'</span>; <span class="hljs-keyword">import</span> { ItemService } from <span class="hljs-string">'./item.service'</span>; <span class="hljs-keyword">import</span> { getModelToken } from <span class="hljs-string">'@nestjs/mongoose'</span>; <span class="hljs-keyword">import</span> { NotFoundException } from <span class="hljs-string">'@nestjs/common'</span>;

describe(<span class="hljs-string">'ItemService'</span>, () => { let service: ItemService; let mockItemModel;

beforeEach(<span class="hljs-keyword">async</span> () => { mockItemModel = { find: jest.fn(), findById: jest.fn(), findByIdAndUpdate: jest.fn(), findByIdAndRemove: jest.fn(), create: jest.fn(), };

<span class="hljs-keyword">const</span> module: TestingModule = <span class="hljs-keyword">await</span> Test.createTestingModule({
  providers: [
    ItemService,
    {
      provide: getModelToken(<span class="hljs-string">'Item'</span>),
      useValue: mockItemModel,
    },
  ],
}).compile();

service = module.<span class="hljs-keyword">get</span>&lt;ItemService&gt;(ItemService);

});

it(<span class="hljs-string">'should be defined'</span>, () => { expect(service).toBeDefined(); });

describe(<span class="hljs-string">'findAll'</span>, () => { it(<span class="hljs-string">'should return an array of items'</span>, <span class="hljs-keyword">async</span> () => { <span class="hljs-keyword">const</span> result = []; mockItemModel.find.mockResolvedValue(result); expect(<span class="hljs-keyword">await</span> service.findAll()).toBe(result); }); });

describe(<span class="hljs-string">'findOne'</span>, () => { it(<span class="hljs-string">'should retrieve an item by its ID'</span>, <span class="hljs-keyword">async</span> () => { <span class="hljs-keyword">const</span> result = { _id: <span class="hljs-string">'some-id'</span>, name: <span class="hljs-string">'ItemName'</span> }; mockItemModel.findById.mockResolvedValue(result); expect(<span class="hljs-keyword">await</span> service.findOne(<span class="hljs-string">'some-id'</span>)).toBe(result); });

it(<span class="hljs-string">'should throw NotFoundException when item does not exist'</span>, <span class="hljs-keyword">async</span> () =&gt; {
  mockItemModel.findById.mockResolvedValue(<span class="hljs-keyword">null</span>);
  <span class="hljs-keyword">await</span> expect(service.findOne(<span class="hljs-string">'some-id'</span>)).rejects.toThrow(NotFoundException);
});

});

describe(<span class="hljs-string">'create'</span>, () => { it(<span class="hljs-string">'should successfully insert an item'</span>, <span class="hljs-keyword">async</span> () => { <span class="hljs-keyword">const</span> createItemDto = { name: <span class="hljs-string">'NewItem'</span> }; mockItemModel.create.mockResolvedValue(createItemDto); expect(<span class="hljs-keyword">await</span> service.create(createItemDto)).toBe(createItemDto); }); });

describe(<span class="hljs-string">'update'</span>, () => { it(<span class="hljs-string">'should update an item'</span>, <span class="hljs-keyword">async</span> () =&

Options

gt; { <span class="hljs-keyword">const</span> result = { _id: <span class="hljs-string">'some-id'</span>, name: <span class="hljs-string">'UpdatedName'</span> }; <span class="hljs-keyword">const</span> updateItemDto = { name: <span class="hljs-string">'UpdatedName'</span> }; mockItemModel.findByIdAndUpdate.mockResolvedValue(result); expect(<span class="hljs-keyword">await</span> service.update(<span class="hljs-string">'some-id'</span>, updateItemDto)).toBe(result); });

it(<span class="hljs-string">'should throw NotFoundException when item does not exist'</span>, <span class="hljs-keyword">async</span> () =&gt; {
  mockItemModel.findByIdAndUpdate.mockResolvedValue(<span class="hljs-keyword">null</span>);
  <span class="hljs-keyword">await</span> expect(service.update(<span class="hljs-string">'some-id'</span>, {})).rejects.toThrow(NotFoundException);
});

});

describe(<span class="hljs-string">'delete'</span>, () => { it(<span class="hljs-string">'should delete an item by its ID'</span>, <span class="hljs-keyword">async</span> () => { <span class="hljs-keyword">const</span> result = { _id: <span class="hljs-string">'some-id'</span>, name: <span class="hljs-string">'ItemToDelete'</span> }; mockItemModel.findByIdAndRemove.mockResolvedValue(result); expect(<span class="hljs-keyword">await</span> service.delete(<span class="hljs-string">'some-id'</span>)).toBe(result); });

it(<span class="hljs-string">'should throw NotFoundException when item does not exist'</span>, <span class="hljs-keyword">async</span> () =&gt; {
  mockItemModel.findByIdAndRemove.mockResolvedValue(<span class="hljs-keyword">null</span>);
  <span class="hljs-keyword">await</span> expect(service.delete(<span class="hljs-string">'some-id'</span>)).rejects.toThrow(NotFoundException);
});

}); });</pre></div><h1 id="ceb6">E2E Testing:</h1><p id="33a2">Testing the Service:</p><p id="4f53">create new file <code>item.e2e-spec.ts</code>:</p><div id="6d4c"><pre><span class="hljs-keyword">import</span> { <span class="hljs-title class_">Test</span>, <span class="hljs-title class_">TestingModule</span> } <span class="hljs-keyword">from</span> <span class="hljs-string">'@nestjs/testing'</span>; <span class="hljs-keyword">import</span> { <span class="hljs-title class_">INestApplication</span> } <span class="hljs-keyword">from</span> <span class="hljs-string">'@nestjs/common'</span>; <span class="hljs-keyword">import</span> * <span class="hljs-keyword">as</span> request <span class="hljs-keyword">from</span> <span class="hljs-string">'supertest'</span>; <span class="hljs-keyword">import</span> { <span class="hljs-title class_">AppModule</span> } <span class="hljs-keyword">from</span> <span class="hljs-string">'./../src/app.module'</span>;

<span class="hljs-title function_">describe</span>(<span class="hljs-string">'ItemController (e2e)'</span>, <span class="hljs-function">() =></span> { <span class="hljs-keyword">let</span> <span class="hljs-attr">app</span>: <span class="hljs-title class_">INestApplication</span>;

<span class="hljs-title function_">beforeAll</span>(<span class="hljs-keyword">async</span> () =&gt; {
    <span class="hljs-keyword">const</span> <span class="hljs-attr">moduleFixture</span>: <span class="hljs-title class_">TestingModule</span> = <span class="hljs-keyword">await</span> <span class="hljs-title class_">Test</span>.<span class="hljs-title function_">createTestingModule</span>({
        <span class="hljs-attr">imports</span>: [<span class="hljs-title class_">AppModule</span>],
    }).<span class="hljs-title function_">compile</span>();

    app = moduleFixture.<span class="hljs-title function_">createNestApplication</span>();
    <span class="hljs-keyword">await</span> app.<span class="hljs-title function_">init</span>();
});

<span class="hljs-title function_">afterAll</span>(<span class="hljs-keyword">async</span> () =&gt; {
    <span class="hljs-keyword">await</span> app.<span class="hljs-title function_">close</span>();
});

<span class="hljs-title function_">it</span>(<span class="hljs-string">'/items (GET)'</span>, <span class="hljs-function">() =&gt;</span> {
    <span class="hljs-keyword">return</span> <span class="hljs-title function_">request</span>(app.<span class="hljs-title function_">getHttpServer</span>())
        .<span class="hljs-title function_">get</span>(<span class="hljs-string">'/items'</span>)
        .<span class="hljs-title function_">expect</span>(<span class="hljs-number">200</span>);
});

<span class="hljs-keyword">let</span> <span class="hljs-attr">itemId</span>: <span class="hljs-built_in">string</span>;

<span class="hljs-title function_">it</span>(<span class="hljs-string">'/items (POST)'</span>, <span class="hljs-function">() =&gt;</span> {
    <span class="hljs-keyword">return</span> <span class="hljs-title function_">request</span>(app.<span class="hljs-title function_">getHttpServer</span>())
        .<span class="hljs-title function_">post</span>(<span class="hljs-string">'/items'</span>)
        .<span class="hljs-title function_">send</span>({ <span class="hljs-attr">name</span>: <span class="hljs-string">'Sample Item'</span>, <span class="hljs-attr">description</span>: <span class="hljs-string">'Sample Description'</span>, <span class="hljs-attr">price</span>: <span class="hljs-number">100</span> })
        .<span class="hljs-title function_">expect</span>(<span class="hljs-number">201</span>)
        .<span class="hljs-title function_">then</span>(<span class="hljs-function"><span class="hljs-params">response</span> =&gt;</span> {
            itemId = response.<span class="hljs-property">body</span>.<span class="hljs-property">_id</span>; <span class="hljs-comment">// Assuming the response contains the created item with its ID</span>
        });
});

<span class="hljs-title function_">it</span>(<span class="hljs-string">'/items/:id (GET)'</span>, <span class="hljs-function">() =&gt;</span> {
    <span class="hljs-keyword">return</span> <span class="hljs-title function_">request</span>(app.<span class="hljs-title function_">getHttpServer</span>())
        .<span class="hljs-title function_">get</span>(<span class="hljs-string">`/items/<span class="hljs-subst">${itemId}</span>`</span>)
        .<span class="hljs-title function_">expect</span>(<span class="hljs-number">200</span>)
        .<span class="hljs-title function_">expect</span>(<span class="hljs-function"><span class="hljs-params">response</span> =&gt;</span> {
            <span class="hljs-title function_">expect</span>(response.<span class="hljs-property">body</span>.<span class="hljs-property">name</span>).<span class="hljs-title function_">toEqual</span>(<span class="hljs-string">'Sample Item'</span>);
        });
});

<span class="hljs-title function_">it</span>(<span class="hljs-string">'/items/:id (PUT)'</span>, <span class="hljs-function">() =&gt;</span> {
    <span class="hljs-keyword">return</span> <span class="hljs-title function_">request</span>(app.<span class="hljs-title function_">getHttpServer</span>())
        .<span class="hljs-title function_">put</span>(<span class="hljs-string">`/items/<span class="hljs-subst">${itemId}</span>`</span>)
        .<span class="hljs-title function_">send</span>({ <span class="hljs-attr">name</span>: <span class="hljs-string">'Updated Item'</span> })
        .<span class="hljs-title function_">expect</span>(<span class="hljs-number">200</span>);
});

<span class="hljs-title function_">it</span>(<span class="hljs-string">'/items/:id (DELETE)'</span>, <span class="hljs-function">() =&gt;</span> {
    <span class="hljs-keyword">return</span> <span class="hljs-title function_">request</span>(app.<span class="hljs-title function_">getHttpServer</span>())
        .<span class="hljs-title function_">delete</span>(<span class="hljs-string">`/items/<span class="hljs-subst">${itemId}</span>`</span>)
        .<span class="hljs-title function_">expect</span>(<span class="hljs-number">200</span>);
});

});

</pre></div><h1 id="53b2">Conclusion:</h1><p id="36d8">This is a basic setup to create a CRUD application using NestJS with MongoDB and then test it. You can expand this app by adding validation, error handling, and other features as needed. The combination of NestJS and MongoDB offers powerful capabilities, and testing ensures that your application behaves as expected.</p></article></body>

The 3 Simple Tenets of Personal Finance: All You Need for an Intentional Life

They’re so simple you’ll hesitate to put them into action, but you must!

Yes, put these in action now! Photo by Tim Mossholder on Unsplash

For the longest time, I was seeking the holy grail of personal finance.

I was chasing get-rich-quick ideas for investments, businesses, and the American Dream.

But after 20-plus years of reading money, personal development, and lifestyle books and blogs, I realized I just wanted to live an intentional life.

One where I prioritized my interests and goals and disengaged with time-suckers and energy-wasters.

And I found it!

The secret to an intentional life is being intentional with my money.

It was so simple — almost too easy to believe — and relied on three simple tenets of personal finance.

Forget all the rest of the money advice and focus on these.

1/ Spend less than you earn.

I know you’ve heard this before, and you’re sick of it.

But it’s the only reason you can’t get ahead in life.

And it creates the foundation for all your future money decisions (as well as the next two tenets of personal finance).

If you can manage your money as if your life depended on it (because it does), then you’ll easily reach your financial dreams.

Do whatever you need to do to meet this requirement. Anything. This is priority #1 for you!

After you consistently spend less than you earn, move to tenet number 2 and chase your intentional life.

2/ Invest, invest, invest.

The earlier you invest your excess money, the more opportunities you have in life.

  • If you start in your 20s, maybe you can retire by age 40!
  • If you start in your 40s, maybe you can retire by 55!
  • If you start in your 50s, maybe you can retire with enough money to survive…

See how quickly that changes?

The earlier, the better.

Anything you can. And as much as you can (and still meet tenet number 3).

And don’t complicate this by being afraid of where to invest your money. Pick a broad-based index fund (like VTI) and put it in. Adjust after you have your money system created and running smoothly.

3/ Balance now vs. the future.

There’s no guarantee you’ll reach your early retirement of 55 — and many of you won’t.

Don’t invest in the future and deprive yourself of living today.

Balance what brings you the most joy now (travel, sports, children, books) with the future you want (early retirement, living overseas, golfing every day).

How do you find this balance?

Pick those absolute-must-do items for today’s life.

Find the money for those and make sure you prioritize it.

This will get you through the day-to-day doldrums of your 9–5 as your investments begin to work for you.

Now cut out everything else and put this excess money toward your investments and your future.

By focusing on your priorities and discarding everything else, you’re more intentional with your money.

Each dollar is focused on something important to you (enjoying today, preparing for tomorrow). It’s not wasted on thoughtless, useless costs.

But Quinn, it sounds too easy.

I know you’re thinking it — “Whatever, Quinn, that’s too easy, and it won’t work for me.”

But try it.

Give it a few months and work your way down the three tenets.

I promise you won’t be disappointed.

tl;dr

The three simple tenets of personal finance:

  1. Spend less than you earn.
  2. Invest, invest, invest.
  3. Balance now vs. the future.

Interested in continuing your Intentional Life? Please follow me here on Medium or sign-up for my newsletter — Intentional Money.

This article is for informational purposes only. It should not be considered Financial or Legal Advice. Not all information will be accurate. Consult a financial professional before making any significant financial decisions.

Continue your reading with these articles —

Personal Finance
Money
Life
Intentional Living
Finance
Recommended from ReadMedium